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 --- pcitool/camera.xml | 923 ++++++++++++++++++++++++++++++++++++++++ pcitool/cli.c | 11 +- pcitool/config.txt | 13 + pcitool/registers_and_banks.xsd | 242 +++++++++++ 4 files changed, 1188 insertions(+), 1 deletion(-) create mode 100644 pcitool/camera.xml create mode 100644 pcitool/config.txt create mode 100755 pcitool/registers_and_banks.xsd (limited to 'pcitool') diff --git a/pcitool/camera.xml b/pcitool/camera.xml new file mode 100644 index 0000000..753c707 --- /dev/null +++ b/pcitool/camera.xml @@ -0,0 +1,923 @@ + + + + + + bank 0 + 0 + 128 + default + 0x9010 + 0x9000 + 8 + little + %lu + cmosis + CMOSIS CMV2000 Registers + + + + 1 + 0 + 16 + 1088 + 0 + RW + cmosis_number_lines + test + + + 3 + 0 + 16 + 0 + 0 + RW + cmosis_start1 + + + 5 + 0 + 16 + 0 + 0 + RW + cmosis_start2 + + + 7 + 0 + 16 + 0 + 0 + RW + cmosis_start3 + + + 9 + 0 + 16 + 0 + 0 + RW + cmosis_start4 + + + 11 + 0 + 16 + 0 + 0 + RW + cmosis_start5 + + + 13 + 0 + 16 + 0 + 0 + RW + cmosis_start6 + + + 15 + 0 + 16 + 0 + 0 + RW + cmosis_start7 + + + 17 + 0 + 16 + 0 + 0 + RW + cmosis_start8 + + + 19 + 0 + 16 + 0 + 0 + RW + cmosis_number_lines1 + + + 21 + 0 + 16 + 0 + 0 + RW + cmosis_number_lines2 + + + 23 + 0 + 16 + 0 + 0 + RW + cmosis_number_lines3 + + + 25 + 0 + 16 + 0 + 0 + RW + cmosis_number_lines4 + + + 27 + 0 + 16 + 0 + 0 + RW + cmosis_number_lines5 + + + 29 + 0 + 16 + 0 + 0 + RW + cmosis_number_lines6 + + + 31 + 0 + 16 + 0 + 0 + RW + cmosis_number_lines7 + + + 33 + 0 + 16 + 0 + 0 + RW + cmosis_number_lines8 + + + 35 + 0 + 16 + 0 + 0 + RW + cmosis_sub_s + + + 37 + 0 + 16 + 0 + 0 + RW + cmosis_sub_a + + + 39 + 0 + 1 + 1 + 0 + RW + cmosis_color + + + 40 + 0 + 2 + 0 + 0 + RW + cmosis_image_flipping + + + 41 + 0 + 2 + 0 + 0 + RW + cmosis_exp_flags + + + 42 + 0 + 24 + 1088 + 0 + RW + cmosis_exp_time + + formuu3 + enumm3 + + + + 45 + 0 + 24 + 1088 + 0 + RW + cmosis_exp_step + + + 48 + 0 + 24 + 1 + 0 + RW + cmosis_exp_kp1 + + + 51 + 0 + 24 + 1 + 0 + RW + cmosis_exp_kp2 + + + 54 + 0 + 2 + 1 + 0 + RW + cmosis_nr_slopes + + + 55 + 0 + 8 + 1 + 0 + RW + cmosis_exp_seq + + + 56 + 0 + 24 + 1088 + 0 + RW + cmosis_exp_time2 + + + 59 + 0 + 24 + 1088 + 0 + RW + cmosis_exp_step2 + + + 68 + 0 + 2 + 1 + 0 + RW + cmosis_nr_slopes2 + + + 69 + 0 + 8 + 1 + 0 + RW + cmosis_exp_seq2 + + + 70 + 0 + 16 + 1 + 0 + RW + cmosis_number_frames + + + 72 + 0 + 2 + 0 + 0 + RW + cmosis_output_mode + + + 78 + 0 + 12 + 85 + 0 + RW + cmosis_training_pattern + + + 80 + 0 + 18 + 0x3FFFF + 0 + RW + cmosis_channel_en + + + 82 + 0 + 3 + 7 + 0 + RW + cmosis_special_82 + + + 89 + 0 + 8 + 96 + 0 + RW + cmosis_vlow2 + + + 90 + 0 + 8 + 96 + 0 + RW + cmosis_vlow3 + + + 100 + 0 + 14 + 16260 + 0 + RW + cmosis_offset + + + 102 + 0 + 2 + 0 + 0 + RW + cmosis_pga + + + 103 + 0 + 8 + 32 + 0 + RW + cmosis_adc_gain + + + 111 + 0 + 1 + 1 + 0 + RW + cmosis_bit_mode + + + 112 + 0 + 2 + 0 + 0 + RW + cmosis_adc_resolution + + + 115 + 0 + 1 + 1 + 0 + RW + cmosis_special_115 + + + + + + bank 1 + 0 + 0x0200 + default + 0x9000 + 0x9000 + 32 + little + 0x%lx + fpga + IPECamera Registers + + + + 0x00 + 0 + 32 + 0 + 0 + RW + spi_conf_input + + + 0x10 + 0 + 32 + 0 + 0 + R + spi_conf_output + + + 0x20 + 0 + 32 + 0 + 0 + RW + spi_clk_speed + + + 0x30 + 0 + 32 + 0 + 0 + R + firmware_info + + + 0 + 8 + R + firmware_version + + + 8 + 1 + R + firmware_bitmode + + + 12 + 2 + R + adc_resolution + + + 16 + 2 + R + output_mode + + + + + 0x40 + 0 + 32 + 0 + 0 + RW + control + + + 31 + 1 + R + freq + + + + + 0x50 + 0 + 32 + 0 + 0 + R + status + + + 0x54 + 0 + 32 + 0 + 0 + R + status2 + + + 0x58 + 0 + 32 + 0 + 0 + R + status3 + + + 0x5c + 0 + 32 + 0 + 0 + R + fr_status + + + 0x70 + 0 + 32 + 0 + 0 + R + start_address + + + 0x74 + 0 + 32 + 0 + 0 + R + end_address + + + 0x78 + 0 + 32 + 0 + 0 + R + rd_address + + + 0xa0 + 0 + 32 + 0 + 0 + R + fr_param1 + + + 0 + 10 + RW + fr_skip_lines + + + 10 + 11 + RW + fr_num_lines + + + 21 + 11 + RW + fr_start_address + + + + + 0xb0 + 0 + 32 + 0 + all bits + RW + fr_param2 + + + 0 + 11 + RW + fr_threshold_start_line + + + 16 + 10 + RW + fr_area_lines + + + + + 0xc0 + 0 + 32 + 0 + 0 + R + skiped_lines + + + 0xd0 + 0 + 32 + 0 + all bits + RW + fr_thresholds + + + 0xd0 + 0 + 10 + 0 + all bits + RW + fr_pixel_thr + + + 0xd0 + 10 + 11 + 0 + all bits + RW + fr_num_pixel_thr + + + 0xd0 + 21 + 11 + 0 + all bits + RW + fr_num_lines_thr + + + 0x100 + 0 + 32 + 0 + 0 + RW + rawdata_pkt_addr + + + 0x110 + 0 + 32 + 0 + 0 + R + temperature_info + + + 0 + 16 + R + sensor_temperature + + formuu1 + formuu2 + enumm2 + + + + 16 + 3 + R + sensor_temperature_alarms + + + 19 + 10 + RW + fpga_temperature + + formuu1 + enumm1 + + + + 29 + 3 + R + fpga_temperature_alarms + + + + + 0x120 + 0 + 32 + 0 + 0 + R + num_lines + + + 0x130 + 0 + 32 + 0 + 0 + R + start_line + + + 0x140 + 0 + 32 + 0 + 0 + R + exp_time + + + 0x150 + 0 + 32 + 0 + 0 + RW + motor + + + 0 + 5 + RW + motor_phi + + + 5 + 5 + RW + motor_z + + + 10 + 5 + RW + motor_y + + + 15 + 5 + RW + motor_x + + + 20 + 8 + R + adc_gain + + + + + 0x160 + 0 + 32 + 0 + 0 + R + write_status + + + 0x170 + 0 + 32 + 0 + 0 + RW + num_triggers + + + 0x180 + 0 + 32 + 0x280 + 0 + RW + trigger_period + + enumm2 + + + + 0x190 + 0 + 32 + 0 + 0 + R + temperature_sample_period + + + 0x1a0 + 0 + 32 + 0x64 + 0 + RW + ddr_max_frames + + + 0x1b0 + 0 + 32 + 0 + 0 + R + ddr_num_frames + + + + + + DMA bank + 0 + 0x0200 + default + 0x0 + 0x0 + 32 + little + 0x%lx + dma + DMA Registers + + + + + + formuu1 + C + (503975./1024000)*@reg - 27315./100 + (@value + 27315./100)*(102400./503975) +formula to get real fpga temperature from the fpga_temperature register in decimal + + + enumm1 + high + low + enum towards temperatures register + + + formuu2 + C + ((1./4)*(@reg - 1200)) if @freq==0 else ((3./10)*(@reg - 1000)) + 4*@value + 1200 if @freq==0 else (10./3)*@value + 1000 + formula to get real sensor temperature from the sensor_temperature register in decimal + + + enumm2 + high + low + enum towards sensor_temperature register + + + formuu3 + us + (@reg+(43./100))*129./(40*1000000)if @freq==0 else (@reg+(43./100))*129./(48*1000000) + @value/129.*(40*1000000) - 43./100 if @freq==0 else @value/129.*(48*1000000) - 43./100 + formula to get real exposure time from the cmosis_exp_time register in decimal + + + enumm3 + short + mid + long + enum towards cmosis_exp_register register + + + diff --git a/pcitool/cli.c b/pcitool/cli.c index 9eeb046..f105349 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -37,6 +37,7 @@ #include "error.h" #include "debug.h" #include "model.h" +#include "xml.h" /* defines */ #define MAX_KBUF 14 @@ -89,7 +90,8 @@ typedef enum { MODE_ALLOC_KMEM, MODE_LIST_KMEM, MODE_READ_KMEM, - MODE_FREE_KMEM + MODE_FREE_KMEM, + MODE_VALIDATE_XML } MODE; typedef enum { @@ -135,6 +137,7 @@ typedef enum { OPT_GRAB = 'g', OPT_QUIETE = 'q', OPT_HELP = 'h', + OPT_VALIDATE_XML= 'v', OPT_RESET = 128, OPT_BENCHMARK, OPT_TRIGGER, @@ -182,6 +185,7 @@ static struct option long_options[] = { {"iterations", required_argument, 0, OPT_ITERATIONS }, {"info", no_argument, 0, OPT_INFO }, {"list", no_argument, 0, OPT_LIST }, + {"validate", no_argument,0,OPT_VALIDATE_XML}, {"reset", no_argument, 0, OPT_RESET }, {"benchmark", optional_argument, 0, OPT_BENCHMARK }, {"read", optional_argument, 0, OPT_READ }, @@ -328,6 +332,8 @@ void Usage(int argc, char *argv[], const char *format, ...) { " Data can be specified as sequence of hexdecimal number or\n" " a single value prefixed with '*'. In this case it will be\n" " replicated the specified amount of times\n" +" XML:\n" +" -v -validates the xml file against xsd" "\n\n", argv[0]); @@ -3122,6 +3128,9 @@ int main(int argc, char **argv) { // Requesting real-time priority when needed switch (mode) { + case MODE_VALIDATE_XML: + validation(); + break; case MODE_READ: case MODE_WRITE: if (amode != ACCESS_DMA) diff --git a/pcitool/config.txt b/pcitool/config.txt new file mode 100644 index 0000000..14bcc57 --- /dev/null +++ b/pcitool/config.txt @@ -0,0 +1,13 @@ +///configuration/// + +pwd to xml model file: +camera.xml + +///pwd to units xml file: +///units.xml +/// +///pwd to python eval file: +///pythonscripts.py +/// +pwd to xsd schema file: +registers_and_banks.xsd diff --git a/pcitool/registers_and_banks.xsd b/pcitool/registers_and_banks.xsd new file mode 100755 index 0000000..10d49b7 --- /dev/null +++ b/pcitool/registers_and_banks.xsd @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 01e63939789b7b6f195bf985dc06151cf5ee780b Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Fri, 3 Jul 2015 12:32:07 +0200 Subject: modified version to include future functions --- pcilib/xml.c | 361 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pcilib/xml.h | 14 ++- pcitool/cli.c | 6 +- 3 files changed, 372 insertions(+), 9 deletions(-) (limited to 'pcitool') 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: 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 ++++++-- pcitool/cli.c | 4 ++-- protocols/default.c | 11 +++++++---- 6 files changed, 34 insertions(+), 9 deletions(-) (limited to 'pcitool') 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; diff --git a/pcitool/cli.c b/pcitool/cli.c index 49d13ee..d24e357 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -989,8 +989,8 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, format = model_info->banks[bank_id].format; if (!format) format = "%lu"; - err = pcilib_read_register_by_id(handle, regid, &value); - // err = pcilib_read_register(handle, bank, reg, &value); + err = pcilib_read_register_by_id(handle, regid, &value); + // err = pcilib_read_register(handle, bank, reg, &value); if (err) printf("Error reading register %s\n", reg); else { printf("%s = ", reg); diff --git a/protocols/default.c b/protocols/default.c index 5e344cf..dd1da54 100644 --- a/protocols/default.c +++ b/protocols/default.c @@ -13,15 +13,18 @@ int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_value_t val = 0; const pcilib_register_bank_description_t *b = bank_ctx->bank; - + printf("bank name %s\n",b->name); + printf("bank bar %i\n",b->bar); + printf("addr %i\n",addr); int access = b->access / 8; - + printf("access : %i\n",access); ptr = pcilib_resolve_register_address(ctx, b->bar, b->read_addr + addr); + // printf("ptr %s\n",ptr); default_datacpy(&val, ptr, access, b); - + printf("val : %i\n",val); // *value = val&BIT_MASK(bits); *value = val; - + printf("value : %i\n",*value); return 0; } -- 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 ++-- pcitool/cli.c | 4 +- 8 files changed, 123 insertions(+), 113 deletions(-) (limited to 'pcitool') 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 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 +- pcitool/cli.c | 6 -- 4 files changed, 132 insertions(+), 119 deletions(-) (limited to 'pcitool') 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. diff --git a/pcitool/cli.c b/pcitool/cli.c index 3a09528..e9c9574 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -93,7 +93,6 @@ typedef enum { MODE_LIST_KMEM, MODE_READ_KMEM, MODE_FREE_KMEM, - MODE_VALIDATE_XML, MODE_LIST_LOCKS, MODE_FREE_LOCKS, MODE_LOCK, @@ -143,7 +142,6 @@ typedef enum { OPT_GRAB = 'g', OPT_QUIETE = 'q', OPT_HELP = 'h', - OPT_VALIDATE_XML= 'v', OPT_RESET = 128, OPT_BENCHMARK, OPT_TRIGGER, @@ -195,7 +193,6 @@ static struct option long_options[] = { {"iterations", required_argument, 0, OPT_ITERATIONS }, {"info", no_argument, 0, OPT_INFO }, {"list", no_argument, 0, OPT_LIST }, - {"validate", no_argument,0,OPT_VALIDATE_XML}, {"reset", no_argument, 0, OPT_RESET }, {"benchmark", optional_argument, 0, OPT_BENCHMARK }, {"read", optional_argument, 0, OPT_READ }, @@ -3299,9 +3296,6 @@ int main(int argc, char **argv) { } switch (mode) { - case MODE_VALIDATE_XML: - validation(); - break; case MODE_INFO: Info(handle, model_info); break; -- 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 ++-- pcitool/cli.c | 3 +- 9 files changed, 205 insertions(+), 241 deletions(-) (limited to 'pcitool') 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") /** #include @@ -3395,6 +3394,8 @@ int main(int argc, char **argv) { pcilib_close(handle); if (data != argv + optind) free(data); + + pcilib_clean_xml(handle); return err; } -- cgit v1.2.3 From d996fab54c59ca0b34d4ff7c4ab5ab8247559db0 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Mon, 7 Sep 2015 10:35:48 +0200 Subject: further modifications --- models/ipecamera/camera.xml | 167 +++++++++++++------------- models/ipecamera/registers_and_banks.xsd | 7 +- pcilib/pci.c | 10 +- pcilib/pci.h | 4 +- pcilib/xml.c | 200 ++++++++++++++++--------------- pcilib/xml.h | 6 +- pcitool/cli.c | 2 - 7 files changed, 205 insertions(+), 191 deletions(-) (limited to 'pcitool') diff --git a/models/ipecamera/camera.xml b/models/ipecamera/camera.xml index 0188267..288f6a4 100644 --- a/models/ipecamera/camera.xml +++ b/models/ipecamera/camera.xml @@ -3,12 +3,11 @@ - bank 0 0 128 default - 0x9010 - 0x9000 + 0x9010 + 0x9000 8 little %lu @@ -17,7 +16,7 @@ - 1 +
1
0 16 1088 @@ -27,7 +26,7 @@ test
- 3 +
3
0 16 0 @@ -36,7 +35,7 @@ cmosis_start1
- 5 +
5
0 16 0 @@ -45,7 +44,7 @@ cmosis_start2
- 7 +
7
0 16 0 @@ -54,7 +53,7 @@ cmosis_start3
- 9 +
9
0 16 0 @@ -63,7 +62,7 @@ cmosis_start4
- 11 +
11
0 16 0 @@ -72,7 +71,7 @@ cmosis_start5
- 13 +
13
0 16 0 @@ -81,7 +80,7 @@ cmosis_start6
- 15 +
15
0 16 0 @@ -90,7 +89,7 @@ cmosis_start7
- 17 +
17
0 16 0 @@ -99,7 +98,7 @@ cmosis_start8
- 19 +
19
0 16 0 @@ -108,7 +107,7 @@ cmosis_number_lines1
- 21 +
21
0 16 0 @@ -117,7 +116,7 @@ cmosis_number_lines2
- 23 +
23
0 16 0 @@ -126,7 +125,7 @@ cmosis_number_lines3
- 25 +
25
0 16 0 @@ -135,7 +134,7 @@ cmosis_number_lines4
- 27 +
27
0 16 0 @@ -144,7 +143,7 @@ cmosis_number_lines5
- 29 +
29
0 16 0 @@ -153,7 +152,7 @@ cmosis_number_lines6
- 31 +
31
0 16 0 @@ -162,7 +161,7 @@ cmosis_number_lines7
- 33 +
33
0 16 0 @@ -171,7 +170,7 @@ cmosis_number_lines8
- 35 +
35
0 16 0 @@ -180,7 +179,7 @@ cmosis_sub_s
- 37 +
37
0 16 0 @@ -189,7 +188,7 @@ cmosis_sub_a
- 39 +
39
0 1 1 @@ -198,7 +197,7 @@ cmosis_color
- 40 +
40
0 2 0 @@ -207,7 +206,7 @@ cmosis_image_flipping
- 41 +
41
0 2 0 @@ -216,7 +215,7 @@ cmosis_exp_flags
- 42 +
42
0 24 1088 @@ -229,7 +228,7 @@
- 45 +
45
0 24 1088 @@ -238,7 +237,7 @@ cmosis_exp_step
- 48 +
48
0 24 1 @@ -247,7 +246,7 @@ cmosis_exp_kp1
- 51 +
51
0 24 1 @@ -256,7 +255,7 @@ cmosis_exp_kp2
- 54 +
54
0 2 1 @@ -265,7 +264,7 @@ cmosis_nr_slopes
- 55 +
55
0 8 1 @@ -274,7 +273,7 @@ cmosis_exp_seq
- 56 +
56
0 24 1088 @@ -283,7 +282,7 @@ cmosis_exp_time2
- 59 +
59
0 24 1088 @@ -292,7 +291,7 @@ cmosis_exp_step2
- 68 +
68
0 2 1 @@ -301,7 +300,7 @@ cmosis_nr_slopes2
- 69 +
69
0 8 1 @@ -310,7 +309,7 @@ cmosis_exp_seq2
- 70 +
70
0 16 1 @@ -319,7 +318,7 @@ cmosis_number_frames
- 72 +
72
0 2 0 @@ -328,7 +327,7 @@ cmosis_output_mode
- 78 +
78
0 12 85 @@ -337,7 +336,7 @@ cmosis_training_pattern
- 80 +
80
0 18 0x3FFFF @@ -346,7 +345,7 @@ cmosis_channel_en
- 82 +
82
0 3 7 @@ -355,7 +354,7 @@ cmosis_special_82
- 89 +
89
0 8 96 @@ -364,7 +363,7 @@ cmosis_vlow2
- 90 +
90
0 8 96 @@ -373,7 +372,7 @@ cmosis_vlow3
- 100 +
100
0 14 16260 @@ -382,7 +381,7 @@ cmosis_offset
- 102 +
102
0 2 0 @@ -391,7 +390,7 @@ cmosis_pga
- 103 +
103
0 8 32 @@ -400,7 +399,7 @@ cmosis_adc_gain
- 111 +
111
0 1 1 @@ -409,7 +408,7 @@ cmosis_bit_mode
- 112 +
112
0 2 0 @@ -418,7 +417,7 @@ cmosis_adc_resolution
- 115 +
115
0 1 1 @@ -430,12 +429,11 @@
- bank 1 0 0x0200 default - 0x9000 - 0x9000 + 0x9000 + 0x9000 32 little 0x%lx @@ -444,7 +442,7 @@ - 0x00 +
0x00
0 32 0 @@ -453,7 +451,7 @@ spi_conf_input
- 0x10 +
0x10
0 32 0 @@ -462,7 +460,7 @@ spi_conf_output
- 0x20 +
0x20
0 32 0 @@ -471,7 +469,7 @@ spi_clk_speed
- 0x30 +
0x30
0 32 0 @@ -506,7 +504,7 @@
- 0x40 +
0x40
0 32 0 @@ -523,7 +521,7 @@
- 0x50 +
0x50
0 32 0 @@ -532,7 +530,7 @@ status
- 0x54 +
0x54
0 32 0 @@ -541,7 +539,7 @@ status2
- 0x58 +
0x58
0 32 0 @@ -550,7 +548,7 @@ status3
- 0x5c +
0x5c
0 32 0 @@ -559,7 +557,7 @@ fr_status
- 0x70 +
0x70
0 32 0 @@ -568,7 +566,7 @@ start_address
- 0x74 +
0x74
0 32 0 @@ -577,7 +575,7 @@ end_address
- 0x78 +
0x78
0 32 0 @@ -586,7 +584,7 @@ rd_address
- 0xa0 +
0xa0
0 32 0 @@ -615,7 +613,7 @@
- 0xb0 +
0xb0
0 32 0 @@ -638,7 +636,7 @@
- 0xc0 +
0xc0
0 32 0 @@ -647,7 +645,7 @@ skiped_lines
- 0xd0 +
0xd0
0 32 0 @@ -656,7 +654,7 @@ fr_thresholds
- 0xd0 +
0xd0
0 10 0 @@ -665,7 +663,7 @@ fr_pixel_thr
- 0xd0 +
0xd0
10 11 0 @@ -674,7 +672,7 @@ fr_num_pixel_thr
- 0xd0 +
0xd0
21 11 0 @@ -683,7 +681,7 @@ fr_num_lines_thr
- 0x100 +
0x100
0 32 0 @@ -692,7 +690,7 @@ rawdata_pkt_addr
- 0x110 +
0x110
0 32 0 @@ -736,7 +734,7 @@
- 0x120 +
0x120
0 32 0 @@ -745,7 +743,7 @@ num_lines
- 0x130 +
0x130
0 32 0 @@ -754,7 +752,7 @@ start_line
- 0x140 +
0x140
0 32 0 @@ -763,7 +761,7 @@ exp_time
- 0x150 +
0x150
0 32 0 @@ -804,7 +802,7 @@
- 0x160 +
0x160
0 32 0 @@ -813,7 +811,7 @@ write_status
- 0x170 +
0x170
0 32 0 @@ -822,7 +820,7 @@ num_triggers
- 0x180 +
0x180
0 32 0x280 @@ -834,7 +832,7 @@
- 0x190 +
0x190
0 32 0 @@ -843,7 +841,7 @@ temperature_sample_period
- 0x1a0 +
0x1a0
0 32 0x64 @@ -852,7 +850,7 @@ ddr_max_frames
- 0x1b0 +
0x1b0
0 32 0 @@ -864,12 +862,11 @@
- DMA bank 0 0x0200 default - 0x0 - 0x0 + 0x0 + 0x0 32 little 0x%lx diff --git a/models/ipecamera/registers_and_banks.xsd b/models/ipecamera/registers_and_banks.xsd index 10d49b7..234cc05 100755 --- a/models/ipecamera/registers_and_banks.xsd +++ b/models/ipecamera/registers_and_banks.xsd @@ -49,12 +49,11 @@ - - - + + @@ -72,7 +71,7 @@ - + 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; /**