From f82813bfa40193aec07e013b029eec6dc092ecdd Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Wed, 1 Jul 2015 16:18:45 +0200 Subject: registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren --- pcilib/CMakeLists.txt | 10 +- pcilib/bank.h | 2 + pcilib/pci.c | 33 +++ pcilib/register.h | 2 + pcilib/xml.c | 672 ++++++++++++++++++++++++++++++++++++++++++++++++++ pcilib/xml.h | 208 ++++++++++++++++ 6 files changed, 923 insertions(+), 4 deletions(-) create mode 100644 pcilib/xml.c create mode 100644 pcilib/xml.h (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index c9bf0fb..881b44c 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -1,11 +1,13 @@ include_directories( ${CMAKE_SOURCE_DIR} + ${PYTHON_INCLUDE_DIRS} + ${XMLLIB_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/pcilib ) -set(HEADERS pcilib.h pci.h export.h bar.h fifo.h model.h bank.h register.h kmem.h irq.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h) -add_library(pcilib SHARED pci.c export.c bar.c fifo.c model.c bank.c register.c kmem.c irq.c dma.c event.c plugin.c tools.c error.c debug.c env.c) -target_link_libraries(pcilib dma protocols ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS}) +set(HEADERS pcilib.h pci.h export.h bar.h fifo.h model.h bank.h register.h kmem.h irq.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h xml.h) +add_library(pcilib SHARED pci.c export.c bar.c fifo.c model.c bank.c register.c kmem.c irq.c dma.c event.c plugin.c tools.c error.c debug.c env.c xml.c) +target_link_libraries(pcilib dma protocols ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${XMLLIB_LIBRARIES} ${PYTHON_LIBRARIES}) add_dependencies(pcilib dma protocols) install(TARGETS pcilib @@ -16,6 +18,6 @@ install(FILES pcilib.h DESTINATION include ) -install(FILES bar.h kmem.h bank.h register.h dma.h event.h model.h error.h debug.h env.h tools.h export.h version.h +install(FILES bar.h kmem.h bank.h register.h dma.h event.h model.h error.h debug.h env.h tools.h export.h version.h xml.h DESTINATION include/pcilib ) diff --git a/pcilib/bank.h b/pcilib/bank.h index a0ba9fe..e2174e9 100644 --- a/pcilib/bank.h +++ b/pcilib/bank.h @@ -62,6 +62,7 @@ typedef struct { const char *format; /**< printf format for the registers, either %lu for decimal output or 0x%lx for hexdecimal */ const char *name; /**< short bank name */ const char *description; /**< longer bank description */ + /* use it or not?*/ /*xmlNodePtr xmlNode;*/ /**model) ctx->model = strdup(model?model:"pci"); + if(registers){ + pcilib_xml_initialize_registers(doc,registers); + pcilib_xml_arrange_registers(registers,number_registers); + pcilib_add_registers(ctx,number_registers,registers); + }else pcilib_error("no memory for registers"); + + if(banks){ + pcilib_xml_initialize_banks(doc,banks); + pcilib_add_register_banks(ctx,number_banks,banks); + }else pcilib_error("no memory for banks"); + ctx->model_info.registers = ctx->registers; ctx->model_info.banks = ctx->banks; ctx->model_info.protocols = ctx->protocols; @@ -166,6 +198,7 @@ pcilib_t *pcilib_open(const char *device, const char *model) { pcilib_close(ctx); return NULL; } + err = pcilib_init_event_engine(ctx); if (err) { diff --git a/pcilib/register.h b/pcilib/register.h index 535e9d0..fc13e6a 100644 --- a/pcilib/register.h +++ b/pcilib/register.h @@ -40,11 +40,13 @@ typedef struct { const char *name; /**< The access name of the register */ const char *description; /**< Brief description of the register */ + /* use it or not? */ /*xmlNodePtr xmlNode;*/ /** +#include +#include +#include +#include + + +/** + * 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){ + xmlDocPtr doc; + doc=xmlParseFile(filename); /**nodesetval)){ + xmlXPathFreeObject(result); +// pcilib_warning("warning : no results found for: %s",xpath); + return NULL; + } + + return result; +} + +/** pcilib_xml_getcontext. + * 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){ + xmlXPathContextPtr context; + context= xmlXPathNewContext(doc); /**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; + /*should we include those xmlnodes?*/ + //myregister->xmlNode=node; +} + +/** 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_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). + * @param[in] doc the AST of the xml file. + * @param[in,out] mybanks the structure containing the banks. + */ +void pcilib_xml_initialize_banks(xmlDocPtr doc, pcilib_register_bank_description_t* mybanks){ + 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; + xmlNodePtr mynode; + + xmlXPathContextPtr context; + context=pcilib_xml_getcontext(doc); + + int i; + + mynode=malloc(sizeof(xmlNode)); + + xmlXPathObjectPtr temp; + + /** we first get the nodes corresponding to the properties we want + * note: here a recursive algorithm may be more efficient but less evolutive*/ + 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"); + + 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"); + + temp=pcilib_xml_getsetproperty(context,BANK_DESCRIPTION_PATH); + if(temp!=NULL)nodesetdescription=temp->nodesetval; + + for(i=0;inodeNr;i++){ + /** we then get each node from the structures above*/ + adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); + bar=xmlNodeListGetString(doc,nodesetbar->nodeTab[i]->xmlChildrenNode, 1); + size=xmlNodeListGetString(doc,nodesetsize->nodeTab[i]->xmlChildrenNode, 1); + protocol=xmlNodeListGetString(doc,nodesetprotocol->nodeTab[i]->xmlChildrenNode, 1); + read_addr=xmlNodeListGetString(doc,nodesetread_addr->nodeTab[i]->xmlChildrenNode, 1); + write_addr=xmlNodeListGetString(doc,nodesetwrite_addr->nodeTab[i]->xmlChildrenNode, 1); + access=xmlNodeListGetString(doc,nodesetaccess->nodeTab[i]->xmlChildrenNode, 1); + endianess=xmlNodeListGetString(doc,nodesetendianess->nodeTab[i]->xmlChildrenNode, 1); + format=xmlNodeListGetString(doc,nodesetformat->nodeTab[i]->xmlChildrenNode, 1); + name=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->xmlChildrenNode, 1); + description=xmlNodeListGetString(doc,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,mynode); + mybanks[i]=mybank; + } + +} + +/** pcilib_xml_create_bank + * + * this function create a bank structure from the results of xml parsing + * @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] node the xmlNodeptr referring to the bank_description node of the bank that will be created. + */ +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, xmlNodePtr node){ + + char* ptr; + + /** 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*/ + + 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,"ipecamera_register")==0){ + mybank->bar=PCILIB_BAR1; + } + + 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->raw_endianess=mybank->endianess; + + mybank->name=(char*)name; + mybank->description=(char*)description; + /* to include or not?*/ + //mybank->xmlNode=node; +} + + +/** 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. + */ +int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ + xmlNodeSetPtr nodesetadress=NULL,nodesetsuboffset=NULL; + xmlXPathObjectPtr temp,temp2; + temp=pcilib_xml_getsetproperty(doc,ADRESS_PATH); /**nodesetval; /**nodesetval;/**< we get the structure with all bits registers here */ + else nodesetsuboffset->nodeNr=0; + return nodesetadress->nodeNr + nodesetsuboffset->nodeNr; /**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; + + for(i=0;inodeNr;i++){ + /** get each sub property of each standard registers*/ + adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); + tempnode=xmlFirstElementChild(xmlFirstElementChild(nodesetadress->nodeTab[i]->parent->parent->parent)); + if(strcmp("adress",(char*)tempnode->name)==0) bank=xmlNodeListGetString(doc,tempnode->xmlChildrenNode,1); + else pcilib_error("the xml file is malformed"); + offset=xmlNodeListGetString(doc,nodesetoffset->nodeTab[i]->xmlChildrenNode, 1); + size=xmlNodeListGetString(doc,nodesetsize->nodeTab[i]->xmlChildrenNode, 1); + defvalue=xmlNodeListGetString(doc,nodesetdefvalue->nodeTab[i]->xmlChildrenNode, 1); + rwmask=xmlNodeListGetString(doc,nodesetrwmask->nodeTab[i]->xmlChildrenNode, 1); + mode=xmlNodeListGetString(doc,nodesetmode->nodeTab[i]->xmlChildrenNode, 1); + name=xmlNodeListGetString(doc,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(doc,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); + registers[i]=myregister; + } + + j=i; + + for(i=0;inodeNr;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(doc,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(doc,tempnode->xmlChildrenNode,1); + else pcilib_error("xml file is malformed"); + suboffset=xmlNodeListGetString(doc,nodesetsuboffset->nodeTab[i]->xmlChildrenNode, 1); + subsize=xmlNodeListGetString(doc,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(doc,tempnode->xmlChildrenNode, 1); + else pcilib_error("xml file is malformed"); + subrwmask=xmlNodeListGetString(doc,nodesetsuboffset->nodeTab[i]->parent->parent->prev->prev->prev->prev->prev->prev->xmlChildrenNode, 1); + submode=xmlNodeListGetString(doc,nodesetsubmode->nodeTab[i]->xmlChildrenNode, 1); + subname=xmlNodeListGetString(doc,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(doc,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,mynode); + registers[i+j]=myregister; + } +} + + +/* + * next 3 functions are for the implementation of a merge sort algorithm + */ +void 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; + + for(j=start;j=end || A[i0].addr<=A[i1].addr)){ + B[j]=A[i0]; + i0++; + } + else{ + B[j]=A[i1]; + i1++; + } + } +} + +void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){ + int k; + for (k=start; k +/** validation + * + * function to validate the xml file against the xsd, so that it does not require extern software + */ +void validation() +{ +xmlDocPtr doc; +xmlSchemaPtr schema = NULL; +xmlSchemaParserCtxtPtr ctxt; + +char *XMLFileName; + pcilib_xml_read_config(&XMLFileName,3); +char *XSDFileName; + pcilib_xml_read_config(&XSDFileName,12); +int ret=1; + +ctxt = xmlSchemaNewParserCtxt(XSDFileName); + +schema = xmlSchemaParse(ctxt); +xmlSchemaFreeParserCtxt(ctxt); + +doc = xmlReadFile(XMLFileName, NULL, 0); + +if (doc == NULL) +{ + pcilib_error("Could not parse xml document "); +} +else +{ +xmlSchemaValidCtxtPtr ctxt; +/** validation here*/ +ctxt = xmlSchemaNewValidCtxt(schema); +ret = xmlSchemaValidateDoc(ctxt, doc); +xmlSchemaFreeValidCtxt(ctxt); +xmlFreeDoc(doc); +} + +//! free the resource +if(schema != NULL) +xmlSchemaFree(schema); + +xmlSchemaCleanupTypes(); +/** print results */ +if (ret == 0) +{ + printf("xml file validates\n"); +} +else +{ + printf("xml file does not validate against the schema\n"); +} + +} + +/** pcilib_xml_read_config + * + * function to get the config we want at line j, in order to be able to have a configuration file with pwd to files we want +* @param[in,out] xmlfile the string representating a pwd to a file we want to access in:uninitilized out: the pwd. +* @param[in] i the line at which the function should read the file to get the pwd. + */ +void pcilib_xml_read_config(char** xmlfile, int j){ + FILE *fp; + + fp=fopen("config.txt","r"); + char line[60]; + memset(line,'\0',60); + int i=0,k; + char *temp1; + if(fp==NULL) pcilib_error("can't find the configuration file: it must be near the executable"); + + while(fgets(line,60,fp)!=NULL){ + if(i==j) { + k=0; + temp1=calloc((strlen(line)),sizeof(char)); + while(line[k]!='\n'){ + temp1[k]=line[k]; + k++; + } + temp1[k]='\0'; + *xmlfile=temp1; + } + i++; + memset(line,'\0',60); + } +} +/* to include or not?*/ +/** pcilib_xml_init_nodeset_register_ctx + * + * function to get all registers nodes in a structure and put it in registers context +* @param[in] ctx the register context running. + * +void pcilib_xml_init_nodeset_register_ctx(pcilib_register_context_t *ctx){ + char* xmlfile; + pcilib_xml_read_config(&xmlfile,3); + xmlDocPtr doc; + doc=pcilib_xml_getdoc(xmlfile); + xmlXPathContextPtr context; + context=pcilib_xml_getcontext(doc); + + xmlNodeSetPtr registers; + registers = pcilib_xml_getsetproperty(context, REGISTERS_PATH)->nodesetval; + ctx->registers_nodes=registers; +} + +** pcilib_xml_init_nodeset_bank_ctx + * + *function to get all banks nodes in a structure and put it in banks context +* @param[in] ctx the bank context running. + * +void pcilib_xml_init_nodeset_bank_ctx(pcilib_register_bank_context_t *ctx){ + char* xmlfile; + pcilib_xml_read_config(&xmlfile,3); + xmlDocPtr doc; + doc=pcilib_xml_getdoc(xmlfile); + xmlXPathContextPtr context; + context=pcilib_xml_getcontext(doc); + + xmlNodeSetPtr banks; + banks = pcilib_xml_getsetproperty(context, BANKS_PATH)->nodesetval; + ctx->banks_nodes=banks; + +} +*/ diff --git a/pcilib/xml.h b/pcilib/xml.h new file mode 100644 index 0000000..da540b5 --- /dev/null +++ b/pcilib/xml.h @@ -0,0 +1,208 @@ +/** + * @file xml.h + * @version 1.0 + * @brief header file to support of xml configuration. + * + * @details this file is the header file for the implementation of dynamic registers using xml and several funtionalities for the "pci-tool" line command tool from XML files. the xml part has been implemented using libxml2. + * + * this code was meant to be evolutive as the XML files evolute. In this meaning, most of the xml parsing is realized with XPath expressions(when it was possible), so that changing the xml xould result mainly in changing the XPAth pathes present here. + * @todo cf compilation chain + */ + +#ifndef _XML_ +#define _XML_ + +//#include +//#include +//#include +//#include + +#include +#include +#include +#include + +#include "pcilib.h" +#include "register.h" +#include "model.h" +#include "bank.h" + +//#include + +#define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /** Date: Fri, 3 Jul 2015 12:32:07 +0200 Subject: modified version to include future functions --- pcilib/xml.c | 361 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pcilib/xml.h | 14 ++- 2 files changed, 369 insertions(+), 6 deletions(-) (limited to 'pcilib') diff --git a/pcilib/xml.c b/pcilib/xml.c index b93f2aa..a9be502 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -19,6 +19,8 @@ #include #include +//#define VIEW_OK +//#define UNIT_OK /** * pcilib_xml_getdoc @@ -670,3 +672,362 @@ void pcilib_xml_init_nodeset_bank_ctx(pcilib_register_bank_context_t *ctx){ } */ + +#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; + +} + +/* 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, + */ +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; + + + +viewnumber=0; + + + 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;inodeNr;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((strlen((char*)name)+51)*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((strlen((char*)name)+strlen(VIEW_BITS_REGISTER_PLUS))*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; jnodeNr;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; jnodeNr;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;jnodeNr;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;uviewsformula[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;lnodeNr;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;uviewsformula[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++; + } +} + +/* 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;inodeNr;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((strlen((char*)name)+51)*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((strlen((char*)name)+strlen(VIEW_BITS_REGISTER_PLUS))*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; jnodeNr;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; jnodeNr;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++; + + } +} +#endif + +#ifdef UNIT_OK + +void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){ + + xmlNodeSetPtr nodesetbaseunit=NULL, nodesettransformunit=NULL; + xmlXPathContextptr context; + context=pcilib_xml_getcontext(doc); + xmlXPathObjectPtr temp; + int i,j; + char *path; + + 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((strlen(unitsptr->list_unit[i].name)+35)*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;jnodeNr;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); + } + } + } + +} +#endif diff --git a/pcilib/xml.h b/pcilib/xml.h index da540b5..f5833aa 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -74,15 +74,17 @@ #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") /** Date: Fri, 3 Jul 2015 18:03:53 +0200 Subject: modified pci to put banks before registers --- pcilib/pci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'pcilib') diff --git a/pcilib/pci.c b/pcilib/pci.c index 5bae8fc..5312922 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -175,17 +175,17 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); + if(banks){ + pcilib_xml_initialize_banks(doc,banks); + pcilib_add_register_banks(ctx,number_banks,banks); + }else pcilib_error("no memory for banks"); + if(registers){ pcilib_xml_initialize_registers(doc,registers); pcilib_xml_arrange_registers(registers,number_registers); pcilib_add_registers(ctx,number_registers,registers); }else pcilib_error("no memory for registers"); - if(banks){ - pcilib_xml_initialize_banks(doc,banks); - pcilib_add_register_banks(ctx,number_banks,banks); - }else pcilib_error("no memory for banks"); - ctx->model_info.registers = ctx->registers; ctx->model_info.banks = ctx->banks; ctx->model_info.protocols = ctx->protocols; -- cgit v1.2.3 From 5a7bcf11b8e3168900a75e7cbf3b1e18f424d271 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Tue, 7 Jul 2015 14:03:39 +0200 Subject: some modif --- pcilib/bar.c | 1 + pcilib/pci.c | 7 +++++++ pcilib/register.c | 12 +++++++++++- pcilib/xml.c | 8 ++++++-- 4 files changed, 25 insertions(+), 3 deletions(-) (limited to 'pcilib') diff --git a/pcilib/bar.c b/pcilib/bar.c index ce04f6d..2c7a8d4 100644 --- a/pcilib/bar.c +++ b/pcilib/bar.c @@ -120,6 +120,7 @@ void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) { } int pcilib_map_register_space(pcilib_t *ctx) { + printf("mapping\n"); int err; pcilib_register_bank_t i; diff --git a/pcilib/pci.c b/pcilib/pci.c index 5312922..76bd59f 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -294,6 +294,7 @@ int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) { char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr) { if (bar == PCILIB_BAR_DETECT) { + printf("bar = PCILIB_BAR_DETECT\n"); // First checking the default register bar size_t offset = addr - ctx->board_info.bar_start[ctx->reg_bar]; if ((addr > ctx->board_info.bar_start[ctx->reg_bar])&&(offset < ctx->board_info.bar_length[ctx->reg_bar])) { @@ -308,6 +309,7 @@ char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t // Otherwise trying to detect bar = pcilib_detect_bar(ctx, addr, 1); if (bar != PCILIB_BAR_INVALID) { + printf("bar pas ainvalid\n"); size_t offset = addr - ctx->board_info.bar_start[bar]; if ((offset < ctx->board_info.bar_length[bar])&&(ctx->bar_space[bar])) { if (!ctx->bar_space[bar]) { @@ -318,16 +320,21 @@ char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t } } } else { + printf("bar internal :%i\n",bar); + // printf("bar invalid\n"); if (!ctx->bar_space[bar]) { pcilib_error("The requested bar (%i) is not mapped", bar); return NULL; } if (addr < ctx->board_info.bar_length[bar]) { + printf("path1\n"); + // printf("apres: %s\n",ctx->bar_space[bar] + addr); return ctx->bar_space[bar] + addr + (ctx->board_info.bar_start[bar] & ctx->page_mask); } if ((addr >= ctx->board_info.bar_start[bar])&&(addr < (ctx->board_info.bar_start[bar] + ctx->board_info.bar_length[ctx->reg_bar]))) { + printf("path2\n"); return ctx->bar_space[bar] + (addr - ctx->board_info.bar_start[bar]) + (ctx->board_info.bar_start[bar] & ctx->page_mask); } } diff --git a/pcilib/register.c b/pcilib/register.c index 347bf7c..5909991 100644 --- a/pcilib/register.c +++ b/pcilib/register.c @@ -91,16 +91,22 @@ static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_ba for (i = 0; i < n; i++) { err = bapi->read(ctx, bctx, addr + i * access, buf + i); + printf("buf +i: %i \n",buf[i]); + if(err) printf("err internal 1: %i\n",err); if (err) break; } if ((bits > 0)&&(!err)) { pcilib_register_value_t val = 0; err = bapi->read(ctx, bctx, addr + n * access, &val); - + val = (val >> offset)&BIT_MASK(bits); + printf("val : %i\n",val); memcpy(buf + n, &val, sizeof(pcilib_register_value_t)); + if(err) printf("err internal 2: %i\n",err); } + printf("err internal 3: %i\n",err); + printf("buf internal: %i\n",buf[0]); return err; } @@ -143,14 +149,18 @@ int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_regi pcilib_error("Big-endian byte order support is not implemented"); return PCILIB_ERROR_NOTSUPPORTED; } else { + printf("bits: %i, n %lu\n",bits, n); res = 0; if (bits) ++n; for (i = 0; i < n; i++) { + printf("res: %i buf[i]: %i\n",res,buf[i]); res |= buf[i] << (i * b->access); + printf("res: %i \n",res); } } *value = res; + printf("value : %i\n",*value); return err; } diff --git a/pcilib/xml.c b/pcilib/xml.c index a9be502..205b563 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -306,8 +306,12 @@ void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* if(strcmp((char*)bar,"0")==0){ mybank->bar=PCILIB_BAR0; - }else if(strcmp((char*)bar,"ipecamera_register")==0){ + }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); @@ -336,7 +340,7 @@ void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* }else if(strcmp((char*)endianess,"host")==0){ mybank->endianess=PCILIB_HOST_ENDIAN; } - + mybank->format=(char*)format; mybank->raw_endianess=mybank->endianess; mybank->name=(char*)name; -- cgit v1.2.3 From d3678e0fcb489eba625347d1209bd8a179153ae0 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 11:09:21 +0200 Subject: put xml nodes pointers for banks and registers in pcilib_t, compil ok --- pcilib/CMakeLists.txt | 6 +- pcilib/bank.h | 1 - pcilib/pci.c | 8 +- pcilib/pci.h | 3 + pcilib/register.h | 1 - pcilib/xml.c | 200 ++++++++++++++++++++++++++------------------------ pcilib/xml.h | 13 ++-- 7 files changed, 121 insertions(+), 111 deletions(-) (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index 774ebe9..428f898 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -5,8 +5,10 @@ include_directories( ${CMAKE_SOURCE_DIR}/pcilib ) -set(HEADERS pcilib.h pci.h export.h bar.h fifo.h model.h bank.h register.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h) -add_library(pcilib SHARED pci.c export.c bar.c fifo.c model.c bank.c register.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c ) +set(HEADERS pcilib.h pci.h export.h bar.h fifo.h model.h bank.h register.h +kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h +env.h version.h config.h xml.h) +add_library(pcilib SHARED pci.c export.c bar.c fifo.c model.c bank.c register.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c xml.c) target_link_libraries(pcilib dma protocols ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${XMLLIB_LIBRARIES} ${PYTHON_LIBRARIES}) add_dependencies(pcilib dma protocols) diff --git a/pcilib/bank.h b/pcilib/bank.h index e2174e9..8074197 100644 --- a/pcilib/bank.h +++ b/pcilib/bank.h @@ -62,7 +62,6 @@ typedef struct { const char *format; /**< printf format for the registers, either %lu for decimal output or 0x%lx for hexdecimal */ const char *name; /**< short bank name */ const char *description; /**< longer bank description */ - /* use it or not?*/ /*xmlNodePtr xmlNode;*/ /**model = strdup(model?model:"pci"); if(banks){ - pcilib_xml_initialize_banks(doc,banks); - pcilib_add_register_banks(ctx,number_banks,banks); + pcilib_xml_initialize_banks(ctx,doc,banks); + pcilib_add_register_banks(ctx,number_banks,banks); }else pcilib_error("no memory for banks"); if(registers){ - pcilib_xml_initialize_registers(doc,registers); - pcilib_xml_arrange_registers(registers,number_registers); + pcilib_xml_initialize_registers(ctx,doc,registers); + pcilib_xml_arrange_registers(registers,number_registers); pcilib_add_registers(ctx,number_registers,registers); }else pcilib_error("no memory for registers"); diff --git a/pcilib/pci.h b/pcilib/pci.h index 340abd3..e3ed1c5 100644 --- a/pcilib/pci.h +++ b/pcilib/pci.h @@ -25,6 +25,7 @@ #include "model.h" #include "export.h" #include "locking.h" +#include typedef struct { uint8_t max_link_speed, link_speed; @@ -71,6 +72,8 @@ 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* banks_xml_nodes; /** #include #include - +#include "pci.h" //#define VIEW_OK //#define UNIT_OK @@ -90,9 +90,8 @@ xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){ * @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 - * @param[in] node the current xmlNode in the xml 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, xmlNodePtr node){ +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; @@ -153,8 +152,6 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlCha myregister->name=(char*)name; myregister->description=(char*)description; - /*should we include those xmlnodes?*/ - //myregister->xmlNode=node; } /** pcilib_xml_getnumberbanks @@ -172,6 +169,90 @@ int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc){ 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 + * @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. + */ +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){ + + char* ptr; + + /** 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*/ + + 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; + + mybank->name=(char*)name; + mybank->description=(char*)description; +} + /** pcilib_xml_initialize_banks * * function to create the structures to store the banks from the AST @@ -179,7 +260,7 @@ int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc){ * @param[in] doc the AST of the xml file. * @param[in,out] mybanks the structure containing the banks. */ -void pcilib_xml_initialize_banks(xmlDocPtr doc, pcilib_register_bank_description_t* mybanks){ +void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc, pcilib_register_bank_description_t* mybanks){ 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; @@ -239,7 +320,10 @@ void pcilib_xml_initialize_banks(xmlDocPtr doc, pcilib_register_bank_description 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;inodeNr;i++){ /** we then get each node from the structures above*/ adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); @@ -255,99 +339,16 @@ void pcilib_xml_initialize_banks(xmlDocPtr doc, pcilib_register_bank_description description=xmlNodeListGetString(doc,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,mynode); + pcilib_xml_create_bank(&mybank,adress,bar,size,protocol,read_addr,write_addr,access,endianess,format, name, description); mybanks[i]=mybank; + pci->banks_xml_nodes[i]=mynode; + } } -/** pcilib_xml_create_bank - * - * this function create a bank structure from the results of xml parsing - * @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] node the xmlNodeptr referring to the bank_description node of the bank that will be created. - */ -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, xmlNodePtr node){ - - char* ptr; - - /** 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*/ - - 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; - - mybank->name=(char*)name; - mybank->description=(char*)description; - /* to include or not?*/ - //mybank->xmlNode=node; -} /** pcilib_xml_getnumberregisters @@ -380,7 +381,7 @@ int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ * @param[in] doc the xpath context of the xml file. * @param[in,out] registers in: initialized list out: the list of the created registers. */ -void pcilib_xml_initialize_registers(xmlDocPtr doc,pcilib_register_description_t *registers){ +void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc,pcilib_register_description_t *registers){ 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; @@ -446,6 +447,9 @@ void pcilib_xml_initialize_registers(xmlDocPtr doc,pcilib_register_description_t pcilib_register_description_t myregister; int i,j; + + pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsuboffset->nodeNr,sizeof(xmlNodePtr)); + if(!(pci->registers_xml_nodes)) pcilib_warning("can't create registers xml nodes in pcilib_t struct"); for(i=0;inodeNr;i++){ /** get each sub property of each standard registers*/ @@ -467,8 +471,9 @@ void pcilib_xml_initialize_registers(xmlDocPtr doc,pcilib_register_description_t } 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); + pcilib_xml_create_register(&myregister,adress,offset,size,defvalue,rwmask,mode, type, bank, name, description); registers[i]=myregister; + pci->registers_xml_nodes[i]=mynode; } j=i; @@ -497,8 +502,9 @@ void pcilib_xml_initialize_registers(xmlDocPtr doc,pcilib_register_description_t } 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,mynode); + pcilib_xml_create_register(&myregister,subadress,suboffset,subsize,subdefvalue,subrwmask,submode, subtype, subbank, subname, subdescription); registers[i+j]=myregister; + pci->registers_xml_nodes[i+j]=mynode; } } diff --git a/pcilib/xml.h b/pcilib/xml.h index f5833aa..3f6d87f 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -26,7 +26,7 @@ #include "register.h" #include "model.h" #include "bank.h" - +#include "pci.h" //#include #define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /** Date: Thu, 27 Aug 2015 12:13:38 +0200 Subject: better public API and no more use of locals within pcilib_open --- pcilib/pci.c | 24 +-------- pcilib/xml.c | 164 ++++++++++++++++++++++++++--------------------------------- pcilib/xml.h | 75 +-------------------------- 3 files changed, 77 insertions(+), 186 deletions(-) (limited to 'pcilib') diff --git a/pcilib/pci.c b/pcilib/pci.c index fa3175d..5d9fedb 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -109,10 +109,6 @@ pcilib_t *pcilib_open(const char *device, const char *model) { size_t i; pcilib_t *ctx = malloc(sizeof(pcilib_t)); - pcilib_register_description_t *registers=NULL; - pcilib_register_bank_description_t *banks=NULL; - int number_registers, number_banks; - char *xmlfile; pcilib_xml_read_config(&xmlfile,3); xmlDocPtr doc; @@ -121,14 +117,6 @@ pcilib_t *pcilib_open(const char *device, const char *model) { xmlXPathContextPtr context; context=pcilib_xml_getcontext(doc); - number_registers=pcilib_xml_getnumberregisters(context); - number_banks=pcilib_xml_getnumberbanks(context); - - if(number_registers)registers=calloc((number_registers),sizeof(pcilib_register_description_t)); - else pcilib_error("no registers in the xml file"); - if(number_banks)banks=calloc((number_banks),sizeof(pcilib_register_bank_description_t)); - else pcilib_error("no banks in the xml file"); - if (!model) model = getenv("PCILIB_MODEL"); @@ -192,16 +180,8 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); - if(banks){ - pcilib_xml_initialize_banks(ctx,doc,banks); - pcilib_add_register_banks(ctx,number_banks,banks); - }else pcilib_error("no memory for banks"); - - if(registers){ - pcilib_xml_initialize_registers(ctx,doc,registers); - pcilib_xml_arrange_registers(registers,number_registers); - pcilib_add_registers(ctx,number_registers,registers); - }else pcilib_error("no memory for registers"); + pcilib_xml_initialize_banks(ctx,doc); + pcilib_xml_initialize_registers(ctx,doc); ctx->model_info.registers = ctx->registers; ctx->model_info.banks = ctx->banks; diff --git a/pcilib/xml.c b/pcilib/xml.c index 762f805..68ac42a 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -19,6 +19,8 @@ #include #include #include "pci.h" +#include "bank.h" +#include "register.h" //#define VIEW_OK //#define UNIT_OK @@ -260,12 +262,14 @@ void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* * @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, pcilib_register_bank_description_t* mybanks){ +void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register_bank_description_t* mybanks*/){ 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; xmlNodePtr mynode; + int number_banks; + pcilib_register_bank_description_t* banks; xmlXPathContextPtr context; context=pcilib_xml_getcontext(doc); @@ -274,10 +278,14 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc, pcilib_register_b mynode=malloc(sizeof(xmlNode)); + number_banks=pcilib_xml_getnumberbanks(context); + if(number_banks) banks=calloc((number_banks),sizeof(pcilib_register_bank_description_t)); + else return; + xmlXPathObjectPtr temp; - /** we first get the nodes corresponding to the properties we want - * note: here a recursive algorithm may be more efficient but less evolutive*/ + /** 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"); @@ -342,14 +350,62 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc, pcilib_register_b /** 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); - mybanks[i]=mybank; + banks[i]=mybank; pci->banks_xml_nodes[i]=mynode; } + + pcilib_add_register_banks(pci,number_banks,banks); +} + +/* + * next 3 functions are for the implementation of a merge sort algorithm + */ +void 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; + for(j=start;j=end || A[i0].addr<=A[i1].addr)){ + B[j]=A[i0]; + i0++; + } + else{ + B[j]=A[i1]; + i1++; + } + } } +void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){ + int k; + for (k=start; knodeNr + nodesetsuboffset->nodeNr; /** 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"); @@ -506,57 +571,12 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc,pcilib_registe registers[i+j]=myregister; pci->registers_xml_nodes[i+j]=mynode; } -} - - -/* - * next 3 functions are for the implementation of a merge sort algorithm - */ -void 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; - - for(j=start;j=end || A[i0].addr<=A[i1].addr)){ - B[j]=A[i0]; - i0++; - } - else{ - B[j]=A[i1]; - i1++; - } - } -} -void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){ - int k; - for (k=start; k /** validation @@ -644,44 +664,6 @@ void pcilib_xml_read_config(char** xmlfile, int j){ memset(line,'\0',60); } } -/* to include or not?*/ -/** pcilib_xml_init_nodeset_register_ctx - * - * function to get all registers nodes in a structure and put it in registers context -* @param[in] ctx the register context running. - * -void pcilib_xml_init_nodeset_register_ctx(pcilib_register_context_t *ctx){ - char* xmlfile; - pcilib_xml_read_config(&xmlfile,3); - xmlDocPtr doc; - doc=pcilib_xml_getdoc(xmlfile); - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - - xmlNodeSetPtr registers; - registers = pcilib_xml_getsetproperty(context, REGISTERS_PATH)->nodesetval; - ctx->registers_nodes=registers; -} - -** pcilib_xml_init_nodeset_bank_ctx - * - *function to get all banks nodes in a structure and put it in banks context -* @param[in] ctx the bank context running. - * -void pcilib_xml_init_nodeset_bank_ctx(pcilib_register_bank_context_t *ctx){ - char* xmlfile; - pcilib_xml_read_config(&xmlfile,3); - xmlDocPtr doc; - doc=pcilib_xml_getdoc(xmlfile); - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - - xmlNodeSetPtr banks; - banks = pcilib_xml_getsetproperty(context, BANKS_PATH)->nodesetval; - ctx->banks_nodes=banks; - -} -*/ #ifdef VIEW_OK /* pcilib_xml_getnumberformulaviews diff --git a/pcilib/xml.h b/pcilib/xml.h index 3f6d87f..a921b3e 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -106,22 +106,7 @@ xmlXPathObjectPtr pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpa * @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,pcilib_register_description_t *registers); - -/** - * this function get the numbers of registers in the xml file for further malloc and xml checking. - * @param[in] doc the xpath context of the xml file. - * @return the numbers of registers in xml file. - * @todo see the usage of this function. - */ -int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc); - -/** - * this function rearrange the list of registers to put them in pcilib_open furthermore, using a merge sort algorithm. The merge sort algorithm was chosen as it's fast and stable, however it uses some memory, but it's not limitating here. - * @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); +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. @@ -129,34 +114,7 @@ void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int s * @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, pcilib_register_bank_description_t* mybanks); - -/** - * this function create a bank from the informations gathered in the xml. - * @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] node the xmlNodeptr referring to the bank_description node of the bank that will be created. - * -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, xmlNodePtr node); -*/ - -/** - * this function get the numbers of banks in the xml file for further malloc and xml checking. - * @param[in] doc the Xpath context of the xml file. - * @return the number of banks. - *@todo see the usage of this function. - */ -int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc); +void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc); /** * this function read the config file of the pcitool tool to give back the pwd of diverse files like the xml file to treat, the xsd file, the pythonscript file, the units xml file, the units xsd file. @@ -179,33 +137,4 @@ void validation(); */ xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc); -/** -* this function is used to register the xpath object containing all registers node in registers context. -* @param[in] ctx the register context running. -*/ -void pcilib_xml_init_nodeset_register_ctx(pcilib_register_context_t *ctx); - -/** -* this function is used to register the xpath object containing all bankss node in banks context. -* @param[in] ctx the bank context running. -*/ -void pcilib_xml_init_nodeset_bank_ctx(pcilib_register_bank_context_t *ctx); - -/** - * 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 - * @param[in] node the current xmlNode in the xml 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, xmlNodePtr node);*/ - #endif /*_XML_*/ -- cgit v1.2.3 From d2ec5ac52105c526390d8a31e52a7a2c260dde80 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 16:19:53 +0200 Subject: xml files get by model and remove of validation mode --- pcilib/pci.c | 17 ++--- pcilib/xml.c | 224 +++++++++++++++++++++++++++++++++-------------------------- pcilib/xml.h | 4 +- 3 files changed, 132 insertions(+), 113 deletions(-) (limited to 'pcilib') diff --git a/pcilib/pci.c b/pcilib/pci.c index 5d9fedb..03b2623 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -109,14 +109,8 @@ pcilib_t *pcilib_open(const char *device, const char *model) { size_t i; pcilib_t *ctx = malloc(sizeof(pcilib_t)); - char *xmlfile; - pcilib_xml_read_config(&xmlfile,3); - xmlDocPtr doc; - doc=pcilib_xml_getdoc(xmlfile); - - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - + xmlDocPtr* docs=NULL; + if (!model) model = getenv("PCILIB_MODEL"); @@ -179,9 +173,10 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); - - pcilib_xml_initialize_banks(ctx,doc); - pcilib_xml_initialize_registers(ctx,doc); + + pcilib_init_xml(docs); + pcilib_xml_initialize_banks(ctx,docs); + pcilib_xml_initialize_registers(ctx,docs); ctx->model_info.registers = ctx->registers; ctx->model_info.banks = ctx->banks; diff --git a/pcilib/xml.c b/pcilib/xml.c index 68ac42a..203b147 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -10,17 +10,18 @@ In case the performance is not good enough, please consider the following : no more configuration file indicating where the files required are, hard code of formulas, and go to complete non evolutive code : get 1 access to xml file and context, and then make recursive descent to get all you need(investigation of libxml2 source code would be so needed to prove it's better to go recursive than just xpath). */ - +#define _XOPEN_SOURCE 700 #include "xml.h" #include "error.h" #include #include #include #include -#include +//#include #include "pci.h" #include "bank.h" #include "register.h" +#include //#define VIEW_OK //#define UNIT_OK @@ -79,6 +80,83 @@ xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){ } +/** validation + * + * function to validate the xml file against the xsd, so that it does not require extern software + */ +void validation(char* xml_filename, char* xsd_filename) +{ +xmlDocPtr doc; +xmlSchemaPtr schema = NULL; +xmlSchemaParserCtxtPtr ctxt; +int ret=1; + +ctxt = xmlSchemaNewParserCtxt(xsd_filename); +schema = xmlSchemaParse(ctxt); +xmlSchemaFreeParserCtxt(ctxt); + +doc = xmlReadFile(xml_filename, NULL, 0); + +if (doc == NULL) +{ + pcilib_error("Could not parse xml document "); +} +else +{ +xmlSchemaValidCtxtPtr ctxt; +/** validation here*/ +ctxt = xmlSchemaNewValidCtxt(schema); +ret = xmlSchemaValidateDoc(ctxt, doc); +xmlSchemaFreeValidCtxt(ctxt); +xmlFreeDoc(doc); +} + +//! free the resource +if(schema != NULL) +xmlSchemaFree(schema); +xmlSchemaCleanupTypes(); + +if(ret!=0) pcilib_error("xml file \"%s\" does not validate against the schema",xml_filename); + +} + +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; +} + /** 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 @@ -262,7 +340,7 @@ void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* * @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/*, pcilib_register_bank_description_t* mybanks*/){ +void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* docs){ 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; @@ -270,20 +348,17 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register xmlNodePtr mynode; int number_banks; pcilib_register_bank_description_t* banks; - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - - int i; - + int i,p; + xmlXPathObjectPtr temp; mynode=malloc(sizeof(xmlNode)); - - number_banks=pcilib_xml_getnumberbanks(context); + 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; - xmlXPathObjectPtr temp; - /** 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); @@ -334,17 +409,17 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register for(i=0;inodeNr;i++){ /** we then get each node from the structures above*/ - adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); - bar=xmlNodeListGetString(doc,nodesetbar->nodeTab[i]->xmlChildrenNode, 1); - size=xmlNodeListGetString(doc,nodesetsize->nodeTab[i]->xmlChildrenNode, 1); - protocol=xmlNodeListGetString(doc,nodesetprotocol->nodeTab[i]->xmlChildrenNode, 1); - read_addr=xmlNodeListGetString(doc,nodesetread_addr->nodeTab[i]->xmlChildrenNode, 1); - write_addr=xmlNodeListGetString(doc,nodesetwrite_addr->nodeTab[i]->xmlChildrenNode, 1); - access=xmlNodeListGetString(doc,nodesetaccess->nodeTab[i]->xmlChildrenNode, 1); - endianess=xmlNodeListGetString(doc,nodesetendianess->nodeTab[i]->xmlChildrenNode, 1); - format=xmlNodeListGetString(doc,nodesetformat->nodeTab[i]->xmlChildrenNode, 1); - name=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->xmlChildrenNode, 1); - description=xmlNodeListGetString(doc,nodesetdescription->nodeTab[i]->xmlChildrenNode, 1); + 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; @@ -356,6 +431,8 @@ void pcilib_xml_initialize_banks(pcilib_t* pci, xmlDocPtr doc/*, pcilib_register } pcilib_add_register_banks(pci,number_banks,banks); + p++; + } } /* @@ -438,19 +515,18 @@ int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ * @param[in] doc the xpath context of the xml file. * @param[in,out] registers in: initialized list out: the list of the created registers. */ -void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc/*,pcilib_register_description_t *registers*/){ +void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr* docs){ 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; xmlNodePtr mynode; xmlNodePtr tempnode; xmlXPathContextPtr context; - int number_registers; +int number_registers, count=0; pcilib_register_description_t *registers=NULL; - context=pcilib_xml_getcontext(doc); - mynode=malloc(sizeof(xmlNode)); - +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; @@ -518,19 +594,19 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc/*,pcilib_regis for(i=0;inodeNr;i++){ /** get each sub property of each standard registers*/ - adress=xmlNodeListGetString(doc,nodesetadress->nodeTab[i]->xmlChildrenNode, 1); + 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(doc,tempnode->xmlChildrenNode,1); + if(strcmp("adress",(char*)tempnode->name)==0) bank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1); else pcilib_error("the xml file is malformed"); - offset=xmlNodeListGetString(doc,nodesetoffset->nodeTab[i]->xmlChildrenNode, 1); - size=xmlNodeListGetString(doc,nodesetsize->nodeTab[i]->xmlChildrenNode, 1); - defvalue=xmlNodeListGetString(doc,nodesetdefvalue->nodeTab[i]->xmlChildrenNode, 1); - rwmask=xmlNodeListGetString(doc,nodesetrwmask->nodeTab[i]->xmlChildrenNode, 1); - mode=xmlNodeListGetString(doc,nodesetmode->nodeTab[i]->xmlChildrenNode, 1); - name=xmlNodeListGetString(doc,nodesetname->nodeTab[i]->xmlChildrenNode, 1); + 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(doc,nodesetname->nodeTab[i]->next->next->xmlChildrenNode,1); + description=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->next->next->xmlChildrenNode,1); }else{ description=(xmlChar*)""; } @@ -546,22 +622,22 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc/*,pcilib_regis for(i=0;inodeNr;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(doc,tempnode->xmlChildrenNode, 1); + 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(doc,tempnode->xmlChildrenNode,1); + if(strcmp((char*)tempnode->name,"adress")==0) subbank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1); else pcilib_error("xml file is malformed"); - suboffset=xmlNodeListGetString(doc,nodesetsuboffset->nodeTab[i]->xmlChildrenNode, 1); - subsize=xmlNodeListGetString(doc,nodesetsubsize->nodeTab[i]->xmlChildrenNode, 1); + 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(doc,tempnode->xmlChildrenNode, 1); + if(strcmp((char*)tempnode->name,"default")==0)subdefvalue=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1); else pcilib_error("xml file is malformed"); - subrwmask=xmlNodeListGetString(doc,nodesetsuboffset->nodeTab[i]->parent->parent->prev->prev->prev->prev->prev->prev->xmlChildrenNode, 1); - submode=xmlNodeListGetString(doc,nodesetsubmode->nodeTab[i]->xmlChildrenNode, 1); - subname=xmlNodeListGetString(doc,nodesetsubname->nodeTab[i]->xmlChildrenNode, 1); + 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(doc,nodesetsubname->nodeTab[i]->next->next->xmlChildrenNode,1); + subdescription=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->next->next->xmlChildrenNode,1); }else{ subdescription=(xmlChar*)""; } @@ -574,64 +650,12 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc/*,pcilib_regis pcilib_xml_arrange_registers(registers,number_registers); pcilib_add_registers(pci,number_registers,registers); + count++; + } } -#include -/** validation - * - * function to validate the xml file against the xsd, so that it does not require extern software - */ -void validation() -{ -xmlDocPtr doc; -xmlSchemaPtr schema = NULL; -xmlSchemaParserCtxtPtr ctxt; - -char *XMLFileName; - pcilib_xml_read_config(&XMLFileName,3); -char *XSDFileName; - pcilib_xml_read_config(&XSDFileName,12); -int ret=1; - -ctxt = xmlSchemaNewParserCtxt(XSDFileName); - -schema = xmlSchemaParse(ctxt); -xmlSchemaFreeParserCtxt(ctxt); - -doc = xmlReadFile(XMLFileName, NULL, 0); - -if (doc == NULL) -{ - pcilib_error("Could not parse xml document "); -} -else -{ -xmlSchemaValidCtxtPtr ctxt; -/** validation here*/ -ctxt = xmlSchemaNewValidCtxt(schema); -ret = xmlSchemaValidateDoc(ctxt, doc); -xmlSchemaFreeValidCtxt(ctxt); -xmlFreeDoc(doc); -} - -//! free the resource -if(schema != NULL) -xmlSchemaFree(schema); - -xmlSchemaCleanupTypes(); -/** print results */ -if (ret == 0) -{ - printf("xml file validates\n"); -} -else -{ - printf("xml file does not validate against the schema\n"); -} - -} /** pcilib_xml_read_config * diff --git a/pcilib/xml.h b/pcilib/xml.h index a921b3e..ee7fdbd 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -106,7 +106,7 @@ xmlXPathObjectPtr pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpa * @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); +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. @@ -114,7 +114,7 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr doc); * @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); +void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* doc); /** * this function read the config file of the pcitool tool to give back the pwd of diverse files like the xml file to treat, the xsd file, the pythonscript file, the units xml file, the units xsd file. -- cgit v1.2.3 From 04b33df0407e03175a56096cb7ff79a56bea9e88 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 16:26:48 +0200 Subject: some cleaning --- pcilib/xml.c | 36 ------------------------------------ pcilib/xml.h | 39 ++++----------------------------------- 2 files changed, 4 insertions(+), 71 deletions(-) (limited to 'pcilib') diff --git a/pcilib/xml.c b/pcilib/xml.c index 203b147..482ab25 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -111,7 +111,6 @@ xmlSchemaFreeValidCtxt(ctxt); xmlFreeDoc(doc); } -//! free the resource if(schema != NULL) xmlSchemaFree(schema); xmlSchemaCleanupTypes(); @@ -654,41 +653,6 @@ while(docs[count]!=NULL){ } } - - - -/** pcilib_xml_read_config - * - * function to get the config we want at line j, in order to be able to have a configuration file with pwd to files we want -* @param[in,out] xmlfile the string representating a pwd to a file we want to access in:uninitilized out: the pwd. -* @param[in] i the line at which the function should read the file to get the pwd. - */ -void pcilib_xml_read_config(char** xmlfile, int j){ - FILE *fp; - - fp=fopen("config.txt","r"); - char line[60]; - memset(line,'\0',60); - int i=0,k; - char *temp1; - if(fp==NULL) pcilib_error("can't find the configuration file: it must be near the executable"); - - while(fgets(line,60,fp)!=NULL){ - if(i==j) { - k=0; - temp1=calloc((strlen(line)),sizeof(char)); - while(line[k]!='\n'){ - temp1[k]=line[k]; - k++; - } - temp1[k]='\0'; - *xmlfile=temp1; - } - i++; - memset(line,'\0',60); - } -} - #ifdef VIEW_OK /* pcilib_xml_getnumberformulaviews * diff --git a/pcilib/xml.h b/pcilib/xml.h index ee7fdbd..00d2374 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -85,22 +85,6 @@ */ #define TRANSFORM_UNIT_PATH ((char*)"/units/unit[@name=\"%s\"]/convert_unit") - -/** -* this function takes a string and will create an abtract syntax tree from the xml file represented by the string. -* @param[in] filename the name of the xml file containing registers and banks. -* @return an AST corresponding to the xml file. -*/ -xmlDocPtr pcilib_xml_getdoc(char* filename); - -/** -* this function takes a context from an AST and an XPath expression, to produce a XPath object containing the nodes corresponding to the xpath expression. -* @param[in] doc the xpath context of the xml file. -* @param[in] xpath the value of the xpath expression that will be computed against the context. -* @return the Xpath object with the nodes we wanted. -*/ -xmlXPathObjectPtr pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpath); - /** * 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. @@ -117,24 +101,9 @@ void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr* doc); void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* doc); /** -* this function read the config file of the pcitool tool to give back the pwd of diverse files like the xml file to treat, the xsd file, the pythonscript file, the units xml file, the units xsd file. -* @param[in,out] xmlfile the string representating a pwd to a file we want to access in:uninitilized out: the pwd. -* @param[in] i the line at which the function should read the file to get the pwd. -*/ -void pcilib_xml_read_config(char** xmlfile, int i); - -/** -* this function validates the xml file against the xsd schema defined as the reference. -* @todo change the name of the function if accepted. -* @todo validation of unit file too? -*/ -void validation(); - - -/** -* this function create an XPath context (ie some sort of special AST only for XPath) from the AST of the xml file. -* @param[in] doc the AST of the xml file. -*/ -xmlXPathContextPtr pcilib_xml_getcontext(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 + */ +void pcilib_init_xml(xmlDocPtr* docs); #endif /*_XML_*/ -- cgit v1.2.3 From a1e8741ac0d77ab721a413a283127352d80fb944 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 27 Aug 2015 16:42:27 +0200 Subject: some adressing regarding possible memory leaks --- pcilib/xml.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'pcilib') diff --git a/pcilib/xml.c b/pcilib/xml.c index 482ab25..ad76dcc 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -154,6 +154,15 @@ while((fgets(line,sizeof(line),in))!=NULL) { 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. @@ -481,6 +490,7 @@ void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int s pcilib_register_description_t* temp; temp=malloc(size*sizeof(pcilib_register_description_t)); topdownsplitmerge(registers,0,size,temp); + free(temp); } /** pcilib_xml_getnumberregisters @@ -724,13 +734,13 @@ viewnumber=0; xmlXPathObjectPtr temp,temp2; char* path; - path=malloc((strlen((char*)name)+51)*sizeof(char)); + 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((strlen((char*)name)+strlen(VIEW_BITS_REGISTER_PLUS))*sizeof(char)); + 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; @@ -836,6 +846,9 @@ viewnumber=0; } viewnumber++; } + + free(path); + free(path2); } /* pcilib_xml_initialize_viewsenum @@ -873,13 +886,13 @@ void pcilib_xml_initialize_viewsenum(xmlDocPtr doc, pcilib_view_enum_ptr_t* myvi registernumber=0; char* path; - path=malloc((strlen((char*)name)+51)*sizeof(char)); + 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((strlen((char*)name)+strlen(VIEW_BITS_REGISTER_PLUS))*sizeof(char)); + 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; @@ -973,6 +986,9 @@ void pcilib_xml_initialize_viewsenum(xmlDocPtr doc, pcilib_view_enum_ptr_t* myvi viewnumber++; } + + free(path); + free(path2); } #endif @@ -996,7 +1012,7 @@ void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){ for(i=0; i< nodesetbaseunit->NodeNr; i++){ unitsptr->list_unit[i].name=nodesetbaseunit->nodeTab[i]->properties->children->content; - path=malloc((strlen(unitsptr->list_unit[i].name)+35)*sizeof(char)); + path=malloc(sizeof(char*)); sprintf(path, TRANSFORM_UNIT_PATH, unitsptr->list_unit[i].name); temp=pcilib_xml_getsetproperty(context, path); if(temp!=NULL){ @@ -1008,6 +1024,6 @@ void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){ } } } - + free(path); } #endif -- cgit v1.2.3 From 57149189cb4e15ed38ee34d44450390955e56697 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Fri, 4 Sep 2015 12:52:07 +0200 Subject: almost finished regarding suren remarks --- pcilib/pci.c | 6 +- pcilib/xml.c | 1172 ++++++++++++++++++---------------------------------------- pcilib/xml.h | 90 +---- 3 files changed, 361 insertions(+), 907 deletions(-) (limited to 'pcilib') 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 #include #include -//#include #include "pci.h" #include "bank.h" #include "register.h" #include -//#define VIEW_OK -//#define UNIT_OK -/** - * pcilib_xml_getdoc +#include +#include + +/** 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); /**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); /**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;inodeNr;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;inodeNr;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; knodesetval; /**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; /**type=PCILIB_REGISTER_STANDARD; + bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent))->xmlChildrenNode,1); /**type=PCILIB_REGISTER_BITS; + bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent->parent->parent))->xmlChildrenNode,1);/**parent->parent->children; /**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;inodeNr;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;inodeNr;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;inodeNr;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;inodeNr;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; jnodeNr;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; jnodeNr;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;jnodeNr;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;uviewsformula[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;lnodeNr;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;uviewsformula[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;inodeNr;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; jnodeNr;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; jnodeNr;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;knodesetval; - 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;jnodeNr;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 -//#include -//#include -//#include - -#include -#include -#include -#include - #include "pcilib.h" -#include "register.h" -#include "model.h" -#include "bank.h" -#include "pci.h" -//#include #define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /** Date: Fri, 4 Sep 2015 14:03:48 +0200 Subject: added cleanup --- pcilib/xml.c | 18 ++++++++++-------- pcilib/xml.h | 7 +++++++ 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'pcilib') diff --git a/pcilib/xml.c b/pcilib/xml.c index 55cdf11..257b503 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -244,7 +244,6 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ xmlNodeSetPtr nodesetadress=NULL; xmlNodePtr mynode; - pcilib_register_bank_description_t* banks; xmlXPathContextPtr context; int i; @@ -253,21 +252,20 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ /** 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; + if(nodesetadress->nodeNr==0) return; 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"); + if(!(pci->banks_xml_nodes)) pcilib_error("can't create bank xml nodes for pcilib_t struct"); - /** for each of the bank nodes, we create the associated structure*/ + /** for each of the bank nodes, we create the associated structure, and push it in the pcilib environnement*/ for(i=0;inodeNr;i++){ mynode=nodesetadress->nodeTab[i]; pcilib_xml_create_bank(&mybank,mynode,doc); - banks[i]=mybank; + pcilib_add_register_banks(pci,1,&mybank); pci->banks_xml_nodes[i]=mynode; } - /** we push our banks structures in the pcilib environnement*/ - pcilib_add_register_banks(pci,nodesetadress->nodeNr,banks); + + } /* @@ -567,6 +565,10 @@ int pcilib_init_xml(pcilib_t* ctx){ free(line); free(line_xsd); free(docs); + + xmlCleanupParser(); + xmlMemoryDump(); + return 0; } diff --git a/pcilib/xml.h b/pcilib/xml.h index 1ef8ee5..ef08d10 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -12,10 +12,17 @@ #ifndef _XML_ #define _XML_ +/*#include +#include +#include +#include +*/ #include "pcilib.h" #define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /** Date: Fri, 4 Sep 2015 15:45:20 +0200 Subject: qsort enough implementation, and corrected a little unwanted propagating description --- pcilib/xml.c | 48 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) (limited to 'pcilib') diff --git a/pcilib/xml.c b/pcilib/xml.c index 257b503..dfda3cc 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -268,40 +268,20 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ } -/* - * next 2 functions are for the implementation of a merge sort algorithm, because we need a stable algorithm +/** pcilib_xml_registers_compare + * function to compare registers by adress for sorting registers + * @param a one hypothetic register + * @param b one other hypothetic register */ -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; - - for(j=start;j=end || A[i0].addr<=A[i1].addr)){ - B[j]=A[i0]; - i0++; - } - else{ - B[j]=A[i1]; - i1++; - } - } -} +static int +pcilib_xml_compare_registers(void const *a, void const *b){ + const pcilib_register_description_t *pa=a; + const pcilib_register_description_t *pb=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; - 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)); + return pa->addr - pb->addr; } + /** 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 don't consider the adding of registers in order of adress * @param[in,out] registers the list of registers in : not ranged out: ranged. @@ -310,7 +290,7 @@ pcilib_xml_topdownsplitmerge(pcilib_register_description_t *A, int start, int en 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)); - pcilib_xml_topdownsplitmerge(registers,0,size,temp); + qsort(registers,size,sizeof(pcilib_register_description_t),pcilib_xml_compare_registers); free(temp); } @@ -327,6 +307,7 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod xmlNodePtr cur; xmlChar *value; xmlChar *bank; + int i=0; /**we get the children of the register xml nodes, that contains the properties for it*/ cur=mynode->children; @@ -382,12 +363,17 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod /* not implemented yet*/ // myregister->value_max=(pcilib_register_value_t)strtol((char*)value,&ptr,0); }else if(strcmp((char*)cur->name,"description")==0){ + i++; myregister->description=(char*)value; } cur=cur->next; } + /** 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(strcmp((char*)type,"standard")==0){ myregister->type=PCILIB_REGISTER_STANDARD; -- cgit v1.2.3 From ea28e2990ae59e21856d9ae0311cec5b5415237b Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Fri, 4 Sep 2015 20:31:14 +0200 Subject: end of modifications --- pcilib/bar.c | 2 - pcilib/error.c | 1 - pcilib/fifo.c | 1 - pcilib/pci.c | 10 +- pcilib/pci.h | 6 +- pcilib/register.c | 14 +- pcilib/xml.c | 386 ++++++++++++++++++++++++++---------------------------- pcilib/xml.h | 23 ++-- 8 files changed, 203 insertions(+), 240 deletions(-) (limited to 'pcilib') diff --git a/pcilib/bar.c b/pcilib/bar.c index 3dc27c9..418f864 100644 --- a/pcilib/bar.c +++ b/pcilib/bar.c @@ -1,5 +1,4 @@ #define _BSD_SOURCE -#define _DEFAULT_SOURCE #define _POSIX_C_SOURCE 200809L #include @@ -131,7 +130,6 @@ void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) { } int pcilib_map_register_space(pcilib_t *ctx) { - printf("mapping\n"); int err; pcilib_register_bank_t i; diff --git a/pcilib/error.c b/pcilib/error.c index 06af292..2c4296e 100644 --- a/pcilib/error.c +++ b/pcilib/error.c @@ -1,5 +1,4 @@ #define _BSD_SOURCE -#define _DEFAULT_SOURCE #include #include diff --git a/pcilib/fifo.c b/pcilib/fifo.c index 7ed87b8..593400f 100644 --- a/pcilib/fifo.c +++ b/pcilib/fifo.c @@ -1,5 +1,4 @@ #define _BSD_SOURCE -#define _DEFAULT_SOURCE #define _POSIX_C_SOURCE 200809L #include diff --git a/pcilib/pci.c b/pcilib/pci.c index 3a0073b..8bbee2f 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -1,7 +1,6 @@ //#define PCILIB_FILE_IO #define _XOPEN_SOURCE 700 #define _BSD_SOURCE -#define _DEFAULT_SOURCE #define _POSIX_C_SOURCE 200809L #include @@ -173,7 +172,7 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); - pcilib_init_xml(ctx); + pcilib_init_xml(ctx, ctx->model); ctx->model_info.registers = ctx->registers; ctx->model_info.banks = ctx->banks; @@ -282,7 +281,6 @@ int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) { char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr) { if (bar == PCILIB_BAR_DETECT) { - printf("bar = PCILIB_BAR_DETECT\n"); // First checking the default register bar size_t offset = addr - ctx->board_info.bar_start[ctx->reg_bar]; if ((addr > ctx->board_info.bar_start[ctx->reg_bar])&&(offset < ctx->board_info.bar_length[ctx->reg_bar])) { @@ -297,7 +295,6 @@ char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t // Otherwise trying to detect bar = pcilib_detect_bar(ctx, addr, 1); if (bar != PCILIB_BAR_INVALID) { - printf("bar pas ainvalid\n"); size_t offset = addr - ctx->board_info.bar_start[bar]; if ((offset < ctx->board_info.bar_length[bar])&&(ctx->bar_space[bar])) { if (!ctx->bar_space[bar]) { @@ -308,21 +305,16 @@ char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t } } } else { - printf("bar internal :%i\n",bar); - // printf("bar invalid\n"); if (!ctx->bar_space[bar]) { pcilib_error("The requested bar (%i) is not mapped", bar); return NULL; } if (addr < ctx->board_info.bar_length[bar]) { - printf("path1\n"); - // printf("apres: %s\n",ctx->bar_space[bar] + addr); return ctx->bar_space[bar] + addr + (ctx->board_info.bar_start[bar] & ctx->page_mask); } if ((addr >= ctx->board_info.bar_start[bar])&&(addr < (ctx->board_info.bar_start[bar] + ctx->board_info.bar_length[ctx->reg_bar]))) { - printf("path2\n"); return ctx->bar_space[bar] + (addr - ctx->board_info.bar_start[bar]) + (ctx->board_info.bar_start[bar] & ctx->page_mask); } } diff --git a/pcilib/pci.h b/pcilib/pci.h index e3ed1c5..40cb4bf 100644 --- a/pcilib/pci.h +++ b/pcilib/pci.h @@ -25,6 +25,7 @@ #include "model.h" #include "export.h" #include "locking.h" +#include "xml.h" #include typedef struct { @@ -72,8 +73,9 @@ 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* banks_xml_nodes; /**read(ctx, bctx, addr + i * access, buf + i); - printf("buf +i: %i \n",buf[i]); - if(err) printf("err internal 1: %i\n",err); if (err) break; } @@ -101,13 +99,9 @@ static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_ba err = bapi->read(ctx, bctx, addr + n * access, &val); val = (val >> offset)&BIT_MASK(bits); - printf("val : %i\n",val); memcpy(buf + n, &val, sizeof(pcilib_register_value_t)); - if(err) printf("err internal 2: %i\n",err); + } - printf("err internal 3: %i\n",err); - printf("buf internal: %i\n",buf[0]); - return err; } @@ -149,19 +143,15 @@ int pcilib_read_register_by_id(pcilib_t *ctx, pcilib_register_t reg, pcilib_regi pcilib_error("Big-endian byte order support is not implemented"); return PCILIB_ERROR_NOTSUPPORTED; } else { - printf("bits: %i, n %lu\n",bits, n); res = 0; if (bits) ++n; for (i = 0; i < n; i++) { - printf("res: %i buf[i]: %i\n",res,buf[i]); res |= buf[i] << (i * b->access); - printf("res: %i \n",res); } } *value = res; - printf("value : %i\n",*value); - + return err; } diff --git a/pcilib/xml.c b/pcilib/xml.c index dfda3cc..f581b96 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -11,12 +11,18 @@ In case the performance is not good enough, please consider the following : no more configuration file indicating where the files required are, hard code of formulas, and go to complete non evolutive code : get 1 access to xml file and context, and then make recursive descent to get all you need(investigation of libxml2 source code would be so needed to prove it's better to go recursive than just xpath). */ #define _XOPEN_SOURCE 700 + + +#define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /** #include #include -#include +#include #include "pci.h" #include "bank.h" #include "register.h" @@ -25,71 +31,54 @@ #include #include #include - #include #include -/** 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 - */ -static xmlDocPtr -pcilib_xml_getdoc(char* filename){ - xmlDocPtr doc; - doc=xmlParseFile(filename); /**nodesetval)){ - xmlXPathFreeObject(result); - return NULL; + pcilib_warning("the parsing of %s xpath expression resulted in an empty nodeset",(char*)xpath); + xmlXPathFreeObject(result); + return NULL; } return result; } -/** pcilib_xml_getcontext. - * this function create a context in an AST (ie initialize XPAth for the AST). - * @param[in] doc the AST of the xml file. + +/**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 xmlXPathContextPtr -pcilib_xml_getcontext(xmlDocPtr doc){ - xmlXPathContextPtr context; - context= xmlXPathNewContext(doc); /**parent->parent)); } -/** validation + +/** pcilib_xml_validate * 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 + *@return an error code */ static int -validation(char* xml_filename, char* xsd_filename) +pcilib_xml_validate(char* xml_filename, char* xsd_filename) { xmlDocPtr doc; xmlSchemaPtr schema = NULL; @@ -136,11 +125,14 @@ 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_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc, pcilib_t* pci){ char* ptr; xmlNodePtr cur; xmlChar *value; + static int i=0; + int bar_ok=0; + int k=0, name_found=0; cur=mynode->children; /** we place ourselves in the childrens of the bank node*/ @@ -149,84 +141,69 @@ pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr my /** 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; - } + if(strcasecmp((char*)cur->name,"bar")==0){ + mybank->bar=(pcilib_bar_t)(value[0]-'0'); + bar_ok++; - }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){ + }else if(strcasecmp((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){ + }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++; + } + } + + }else if(strcasecmp((char*)cur->name,"read_address")==0){ mybank->read_addr=(uintptr_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"write_adress")==0){ + }else if(strcasecmp((char*)cur->name,"write_address")==0){ mybank->write_addr=(uintptr_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"word_size")==0){ + }else if(strcasecmp((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){ + }else if(strcasecmp((char*)cur->name,"endianess")==0){ + if(strcasecmp((char*)value,"little")==0){ mybank->endianess=PCILIB_LITTLE_ENDIAN; - }else if(strcmp((char*)value,"big")==0){ + }else if(strcasecmp((char*)value,"big")==0){ mybank->endianess=PCILIB_BIG_ENDIAN; - }else if(strcmp((char*)value,"host")==0){ + }else if(strcasecmp((char*)value,"host")==0){ mybank->endianess=PCILIB_HOST_ENDIAN; } mybank->raw_endianess=mybank->endianess; - }else if(strcmp((char*)cur->name,"format")==0){ + }else if(strcasecmp((char*)cur->name,"format")==0){ mybank->format=(char*)value; - }else if(strcmp((char*)cur->name,"name")==0){ + }else if(strcasecmp((char*)cur->name,"name")==0){ mybank->name=(char*)value; - }else if(strcmp((char*)cur->name,"description")==0){ + }else if(strcasecmp((char*)cur->name,"description")==0){ mybank->description=(char*)value; } cur=cur->next; } + + 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++; + } + if(name_found==0) { + mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC + i; + i++; + } + pci->xml_banks[k]=mynode; } @@ -242,36 +219,39 @@ static void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ pcilib_register_bank_description_t mybank; - xmlNodeSetPtr nodesetadress=NULL; + xmlNodeSetPtr nodesetaddress=NULL; xmlNodePtr mynode; xmlXPathContextPtr context; int i; mynode=malloc(sizeof(xmlNode)); - context=pcilib_xml_getcontext(doc); - + if(!(context= xmlXPathNewContext(doc))){ + pcilib_error("can't get an AST from an xml file"); + return; + } /** we get the bank nodes using xpath expression*/ - nodesetadress=pcilib_xml_getsetproperty(context,BANKS_PATH)->nodesetval; - if(nodesetadress->nodeNr==0) return; + nodesetaddress=pcilib_xml_get_nodeset_from_xpath(context,BANKS_PATH)->nodesetval; + if(!(nodesetaddress)) return; + if(nodesetaddress->nodeNr==0) return; - pci->banks_xml_nodes=calloc(nodesetadress->nodeNr,sizeof(xmlNodePtr)); - if(!(pci->banks_xml_nodes)) pcilib_error("can't create bank xml nodes for pcilib_t struct"); + 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"); /** for each of the bank nodes, we create the associated structure, and push it in the pcilib environnement*/ - for(i=0;inodeNr;i++){ - mynode=nodesetadress->nodeTab[i]; - pcilib_xml_create_bank(&mybank,mynode,doc); + for(i=0;inodeNr;i++){ + mynode=nodesetaddress->nodeTab[i]; + pcilib_xml_create_bank(&mybank,mynode,doc, pci); pcilib_add_register_banks(pci,1,&mybank); - pci->banks_xml_nodes[i]=mynode; } } /** pcilib_xml_registers_compare - * function to compare registers by adress for sorting registers + * function to compare registers by address for sorting registers * @param a one hypothetic register * @param b one other hypothetic register + *@return the result of the comparison */ static int pcilib_xml_compare_registers(void const *a, void const *b){ @@ -283,7 +263,7 @@ pcilib_xml_compare_registers(void const *a, void const *b){ /** 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 don't 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 address * @param[in,out] registers the list of registers in : not ranged out: ranged. * @param[in] size the number of registers. */ @@ -301,12 +281,12 @@ 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){ +void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type, pcilib_t* pci){ char* ptr; xmlNodePtr cur; - xmlChar *value; - xmlChar *bank; + xmlChar *value=NULL; + xmlNodePtr bank=NULL; int i=0; /**we get the children of the register xml nodes, that contains the properties for it*/ @@ -317,52 +297,52 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod /* 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){ + if(strcasecmp((char*)cur->name,"address")==0){ myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"offset")==0){ + }else if(strcasecmp((char*)cur->name,"offset")==0){ myregister->offset=(pcilib_register_size_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"size")==0){ + }else if(strcasecmp((char*)cur->name,"size")==0){ myregister->bits=(pcilib_register_size_t)strtol((char*)value,&ptr,0); - }else if(strcmp((char*)cur->name,"default")==0){ + }else if(strcasecmp((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){ + }else if(strcasecmp((char*)cur->name,"rwmask")==0){ + if(strcasecmp((char*)value,"all bits")==0){ myregister->rwmask=PCILIB_REGISTER_ALL_BITS; - }else if(strcmp((char*)value,"0")==0){ + }else if(strcasecmp((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){ + }else if(strcasecmp((char*)cur->name,"mode")==0){ + if(strcasecmp((char*)value,"R")==0){ myregister->mode=PCILIB_REGISTER_R; - }else if(strcmp((char*)value,"W")==0){ + }else if(strcasecmp((char*)value,"W")==0){ myregister->mode=PCILIB_REGISTER_W; - }else if(strcmp((char*)value,"RW")==0){ + }else if(strcasecmp((char*)value,"RW")==0){ myregister->mode=PCILIB_REGISTER_RW; - }else if(strcmp((char*)value,"W")==0){ + }else if(strcasecmp((char*)value,"W")==0){ myregister->mode=PCILIB_REGISTER_W; - }else if(strcmp((char*)value,"RW1C")==0){ + }else if(strcasecmp((char*)value,"RW1C")==0){ myregister->mode=PCILIB_REGISTER_RW1C; - }else if(strcmp((char*)value,"W1C")==0){ + }else if(strcasecmp((char*)value,"W1C")==0){ myregister->mode=PCILIB_REGISTER_W1C; } - }else if(strcmp((char*)cur->name,"name")==0){ + }else if(strcasecmp((char*)cur->name,"name")==0){ myregister->name=(char*)value; - }else if(strcmp((char*)cur->name,"value_min")==0){ + }else if(strcasecmp((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){ + }else if(strcasecmp((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){ + }else if(strcasecmp((char*)cur->name,"description")==0){ i++; myregister->description=(char*)value; } @@ -375,116 +355,106 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod /** we then get properties that can not be parsed as the previous ones*/ - if(strcmp((char*)type,"standard")==0){ + if(strcasecmp((char*)type,"standard")==0){ myregister->type=PCILIB_REGISTER_STANDARD; - bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent))->xmlChildrenNode,1); /**children,1); + if(strcasecmp((char*)bank->name,"name")==0){ + break; + } + bank=bank->next; + } - }else if(strcmp((char*)type,"bits")==0){ - myregister->type=PCILIB_REGISTER_BITS; - bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent->parent->parent))->xmlChildrenNode,1);/**parent->parent->children; /**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); - } + 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; } - cur=cur->next; + k++; } - }else if(strcmp((char*)type,"fifo")==0){ - /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO; - } + }else if(strcasecmp((char*)type,"bits")==0){ + myregister->type=PCILIB_REGISTER_BITS; - 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; + }else if(strcasecmp((char*)type,"fifo")==0){ + /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO; } + + } /** pcilib_xml_initialize_registers * * this function create a list of registers from an abstract syntax tree * - * 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) + * variables who need change if xml structure change : bank,description, sub_description, sub_address, 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] pci the pcilib_t struct running, that will get filled */ void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ - xmlNodeSetPtr nodesetadress=NULL, nodesetsubadress=NULL; - xmlChar *type=NULL; + xmlNodeSetPtr nodesetaddress=NULL, nodesetsubaddress=NULL; xmlNodePtr mynode; xmlXPathContextPtr context; pcilib_register_description_t *registers=NULL; pcilib_register_description_t myregister; int i,j; - context=pcilib_xml_getcontext(doc); + context= xmlXPathNewContext(doc); + if(!(context= xmlXPathNewContext(doc))){ + pcilib_error("can't get an AST from an xml file"); + return; + } /** 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)); + nodesetaddress=pcilib_xml_get_nodeset_from_xpath(context,REGISTERS_PATH)->nodesetval; + nodesetsubaddress=pcilib_xml_get_nodeset_from_xpath(context,BITS_REGISTERS_PATH)->nodesetval; + if(!(nodesetaddress)) return; + if(nodesetaddress->nodeNr>0)registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(pcilib_register_description_t)); else return; - 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"); + 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"); /** we then iterate through standard registers nodes to create registers structures*/ - for(i=0;inodeNr;i++){ - type=(xmlChar*)"standard"; - mynode=nodesetadress->nodeTab[i]; - pcilib_xml_create_register(&myregister,mynode,doc,type); + for(i=0;inodeNr;i++){ + mynode=nodesetaddress->nodeTab[i]; + pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"standard",pci); registers[i]=myregister; - pci->registers_xml_nodes[i]=mynode; + pci->xml_registers[i]=mynode; } j=i; + if(!(nodesetsubaddress)) return; /** we then iterate through bits registers nodes to create registers structures*/ - for(i=0;inodeNr;i++){ - type=(xmlChar*)"bits"; - mynode=nodesetsubadress->nodeTab[i]; - pcilib_xml_create_register(&myregister,mynode,doc,type); + 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); registers[i+j]=myregister; - pci->registers_xml_nodes[i+j]=mynode; + pci->xml_registers[i+j]=mynode; } /**we arrange the register for them to be well placed for pci-l*/ - pcilib_xml_arrange_registers(registers,nodesetadress->nodeNr+nodesetsubadress->nodeNr); + pcilib_xml_arrange_registers(registers,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr); /**we fille the pcilib_t struct*/ - pcilib_add_registers(pci,nodesetadress->nodeNr+nodesetsubadress->nodeNr,registers); + pcilib_add_registers(pci,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,registers); } /** 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 + * @param[in] model the current model of ctx + * @return an error code */ -int pcilib_init_xml(pcilib_t* ctx){ +int pcilib_init_xml(pcilib_t* ctx, char* model){ char *path,*pwd, **line, *line_xsd=NULL; int i=1,k; xmlDocPtr* docs; @@ -504,8 +474,8 @@ int pcilib_init_xml(pcilib_t* ctx){ } /** 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); + pwd=malloc((strlen(path)+strlen(model))*sizeof(char)); + 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; @@ -538,23 +508,35 @@ int pcilib_init_xml(pcilib_t* ctx){ /** for each xml file, we validate it, and get the registers and the banks*/ docs=malloc((i-1)*sizeof(xmlDocPtr)); 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; + free(pwd); free(line); free(line_xsd); - free(docs); - - xmlCleanupParser(); - xmlMemoryDump(); return 0; } +/** pcilib_clean_xml + * 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); + xmlCleanupParser(); + xmlMemoryDump(); + +} diff --git a/pcilib/xml.h b/pcilib/xml.h index ef08d10..c10a9d3 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -12,23 +12,24 @@ #ifndef _XML_ #define _XML_ -/*#include -#include -#include -#include -*/ +#include #include "pcilib.h" -#define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /** 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; /**