/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pcilib/xml.c

  • Committer: zilio nicolas
  • Date: 2015-09-04 18:31:14 UTC
  • mto: This revision was merged to the branch mainline in revision 303.
  • Revision ID: nicolas.zilio@kit.edu-20150904183114-ggzdquen086c033r
end of modifications

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 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).
12
12
 */
13
13
#define _XOPEN_SOURCE 700
 
14
 
 
15
 
 
16
#define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /**<all standard registers nodes.*/
 
17
#define BITS_REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits") /**<all bits registers nodes.*/
 
18
#define BANKS_PATH ((xmlChar*)"/model/banks/bank/bank_description") /**< path to complete nodes of banks.*/
 
19
 
14
20
#include "xml.h"
15
21
#include "error.h"
16
22
#include <stdlib.h>
17
23
#include <stdio.h>
18
24
#include <string.h>
19
 
#include <assert.h>
 
25
#include <strings.h>
20
26
#include "pci.h"
21
27
#include "bank.h"
22
28
#include "register.h"
25
31
#include <libxml/parser.h>
26
32
#include <libxml/xpath.h>
27
33
#include <libxml/xpathInternals.h>
28
 
 
29
34
#include <dirent.h>
30
35
#include <errno.h>
31
36
 
32
 
/** pcilib_xml_getdoc
33
 
 * this function takes a string and will create an abtract syntax tree from the xml file represented by the string
34
 
 * @param[in] filename the the name of the xml file containing registers and banks 
35
 
 */
36
 
static xmlDocPtr
37
 
pcilib_xml_getdoc(char* filename){
38
 
                xmlDocPtr doc;
39
 
                doc=xmlParseFile(filename); /**<the creation of the AST from a libxml2 funtion*/
40
 
                
41
 
                if (doc==NULL){
42
 
                        pcilib_error("xml document not parsed successfully");
43
 
                        return NULL;
44
 
                }
45
 
                
46
 
                return doc;
47
 
}
48
 
 
49
 
/** pcilib_xml_getsetproperty
 
37
/** pcilib_xml_get_nodeset_from_xpath
50
38
 * this function takes a context from an AST and an XPath expression, to produce an object containing the nodes corresponding to the xpath expression
51
39
 * @param[in] doc the AST of the xml file
52
40
 * @param[in] xpath the xpath expression that will be evaluated
 
41
 *@return the nodeset from AST and xpath expression evaluation of the xml file
53
42
 */
54
43
static xmlXPathObjectPtr
55
 
pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpath){
 
44
pcilib_xml_get_nodeset_from_xpath(xmlXPathContextPtr doc, xmlChar *xpath){
56
45
        xmlXPathObjectPtr result;
57
46
        result=xmlXPathEvalExpression(xpath, doc); /**<the creation of the resulting object*/
58
47
        if(result==NULL){
59
 
                return NULL;
 
48
          pcilib_error("can't parse xpath expression %s",(char*)xpath);
 
49
          return NULL;
60
50
        }
61
51
        
62
52
        if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
63
 
                xmlXPathFreeObject(result);
64
 
                return NULL;
 
53
          pcilib_warning("the parsing of %s xpath expression resulted in an empty nodeset",(char*)xpath);
 
54
          xmlXPathFreeObject(result);
 
55
          return NULL;
65
56
        }
66
57
        
67
58
        return result;
68
59
}
69
60
 
70
 
/** pcilib_xml_getcontext.
71
 
 * this function create a context in an AST (ie initialize XPAth for the AST).
72
 
 * @param[in] doc the AST of the xml file.
 
61
 
 
62
/**pcilib_xml_get_bank_node_from_register_node
 
63
 * this function get the bank xml node from a standards register xml node in the xml file
 
64
 *@param[in] mynode the register node we want to know the bank
 
65
 *@return the bank node
73
66
 */
74
 
static xmlXPathContextPtr
75
 
pcilib_xml_getcontext(xmlDocPtr doc){
76
 
  xmlXPathContextPtr context;
77
 
          context= xmlXPathNewContext(doc); /**<the creation of the context using a libxml2's function */
78
 
         if(context==NULL){
79
 
            pcilib_error("warning : no context obtained for the xml document");
80
 
             return NULL;
81
 
                }
82
 
        return context;
 
67
static xmlNodePtr
 
68
pcilib_xml_get_bank_node_from_register_node(xmlNodePtr mynode){
 
69
  return xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent));
83
70
}
84
71
 
85
72
 
86
 
/** validation
 
73
 
 
74
/** pcilib_xml_validate
87
75
 * function to validate the xml file against the xsd
88
76
 * @param[in] xml_filename path to the xml file
89
77
 * @param[in] xsd_filename path to the xsd file
 
78
 *@return an error code
90
79
 */
91
80
static int
92
 
validation(char* xml_filename, char* xsd_filename)
 
81
pcilib_xml_validate(char* xml_filename, char* xsd_filename)
93
82
{
94
83
xmlDocPtr doc;
95
84
xmlSchemaPtr schema = NULL;
136
125
 * @param[in] doc the AST of the xml file, used for used lixbml functions
137
126
 */
138
127
static void
139
 
pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc){
 
128
pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc, pcilib_t* pci){
140
129
                
141
130
    char* ptr;
142
131
    xmlNodePtr cur;
143
132
    xmlChar *value;
 
133
    static int i=0;
 
134
    int bar_ok=0;
 
135
    int k=0, name_found=0;
144
136
 
145
137
    cur=mynode->children; /** we place ourselves in the childrens of the bank node*/
146
138
 
149
141
      /** we get each time the name of the node, corresponding to one property, and the value of the node*/
150
142
      value=xmlNodeListGetString(doc,cur->children,1);
151
143
        
152
 
        if(strcmp((char*)cur->name,"adress")==0){
153
 
            if (strcmp((char*)value,"bank 0")==0){
154
 
              mybank->addr=PCILIB_REGISTER_BANK0;
155
 
            }else if (strcmp((char*)value,"bank 1")==0){
156
 
              mybank->addr=PCILIB_REGISTER_BANK1;
157
 
            }else if (strcmp((char*)value,"bank 2")==0){
158
 
              mybank->addr=PCILIB_REGISTER_BANK2;
159
 
            }else if (strcmp((char*)value,"bank 3")==0){
160
 
              mybank->addr=PCILIB_REGISTER_BANK3;
161
 
            }else if (strcmp((char*)value,"DMA bank")==0){
162
 
              mybank->addr=PCILIB_REGISTER_BANK_DMA;
163
 
            }else if (strcmp((char*)value,"DMAconf bank")==0){
164
 
              mybank->addr=PCILIB_REGISTER_BANK_DMACONF;
165
 
            }else if (strcmp((char*)value,"dynamic bank")==0){
166
 
              mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC;
167
 
            }else{
168
 
              mybank->addr=PCILIB_REGISTER_BANK_INVALID;
169
 
            }
 
144
        if(strcasecmp((char*)cur->name,"bar")==0){
 
145
          mybank->bar=(pcilib_bar_t)(value[0]-'0');
 
146
          bar_ok++;
170
147
 
171
 
        }else if(strcmp((char*)cur->name,"bar")==0){
172
 
            if(strcmp((char*)value,"0")==0){
173
 
              mybank->bar=PCILIB_BAR0;
174
 
            }else if(strcmp((char*)value,"1")==0){
175
 
              mybank->bar=PCILIB_BAR1;
176
 
            }else if(strcmp((char*)value,"no_bar")==0){
177
 
              mybank->bar=PCILIB_BAR_NOBAR;
178
 
            }else{
179
 
              mybank->bar=PCILIB_BAR_INVALID;
180
 
            }
181
 
            mybank->bar=(pcilib_bar_t)strtol((char*)value,&ptr,0);
182
 
        
183
 
        }else if(strcmp((char*)cur->name,"size")==0){
 
148
        }else if(strcasecmp((char*)cur->name,"size")==0){
184
149
            mybank->size=(size_t)strtol((char*)value,&ptr,0);
185
150
        
186
 
        }else if(strcmp((char*)cur->name,"protocol")==0){               
187
 
            if(strcmp((char*)value,"default")==0){
188
 
              mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT;
189
 
            }else if(strcmp((char*)value,"0")==0){
190
 
              mybank->protocol=PCILIB_REGISTER_PROTOCOL0;
191
 
            }else if(strcmp((char*)value,"dma")==0){
192
 
              mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA;
193
 
            }else if(strcmp((char*)value,"dynamic")==0){
194
 
              mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC;
195
 
            }else if (strcmp((char*)value,"software")==0){
196
 
              mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE;
197
 
            }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID;
198
 
        
199
 
        }else if(strcmp((char*)cur->name,"read_adress")==0){            
 
151
        }else if(strcasecmp((char*)cur->name,"protocol")==0){           
 
152
          while(pci->protocols[k].name!=NULL){
 
153
            if(strcasecmp(pci->protocols[k].name,(char*)value)==0){
 
154
              mybank->protocol=pci->protocols[k].addr;
 
155
              break;
 
156
              k++;
 
157
            }
 
158
          }
 
159
 
 
160
        }else if(strcasecmp((char*)cur->name,"read_address")==0){               
200
161
            mybank->read_addr=(uintptr_t)strtol((char*)value,&ptr,0);
201
162
 
202
 
        }else if(strcmp((char*)cur->name,"write_adress")==0){
 
163
        }else if(strcasecmp((char*)cur->name,"write_address")==0){
203
164
              mybank->write_addr=(uintptr_t)strtol((char*)value,&ptr,0);
204
165
        
205
 
        }else if(strcmp((char*)cur->name,"word_size")==0){
 
166
        }else if(strcasecmp((char*)cur->name,"word_size")==0){
206
167
            mybank->access=(uint8_t)strtol((char*)value,&ptr,0);
207
168
        
208
 
        }else if(strcmp((char*)cur->name,"endianess")==0){              
209
 
            if(strcmp((char*)value,"little")==0){
 
169
        }else if(strcasecmp((char*)cur->name,"endianess")==0){          
 
170
            if(strcasecmp((char*)value,"little")==0){
210
171
              mybank->endianess=PCILIB_LITTLE_ENDIAN;
211
 
            }else if(strcmp((char*)value,"big")==0){
 
172
            }else if(strcasecmp((char*)value,"big")==0){
212
173
              mybank->endianess=PCILIB_BIG_ENDIAN;
213
 
            }else if(strcmp((char*)value,"host")==0){
 
174
            }else if(strcasecmp((char*)value,"host")==0){
214
175
              mybank->endianess=PCILIB_HOST_ENDIAN;
215
176
            }           
216
177
            mybank->raw_endianess=mybank->endianess;
217
178
          
218
 
        }else if(strcmp((char*)cur->name,"format")==0){
 
179
        }else if(strcasecmp((char*)cur->name,"format")==0){
219
180
            mybank->format=(char*)value;
220
181
 
221
 
        }else if(strcmp((char*)cur->name,"name")==0){
 
182
        }else if(strcasecmp((char*)cur->name,"name")==0){
222
183
              mybank->name=(char*)value;
223
184
    
224
 
        }else if(strcmp((char*)cur->name,"description")==0){
 
185
        }else if(strcasecmp((char*)cur->name,"description")==0){
225
186
                mybank->description=(char*)value;
226
187
        }
227
188
 
228
189
    cur=cur->next;
229
190
    }
 
191
 
 
192
    if(bar_ok==0) mybank->bar=PCILIB_BAR_NOBAR;
 
193
  
 
194
    while(pci->banks[k].name!=NULL){
 
195
        if(strcasecmp(pci->banks[k].name,mybank->name)==0){
 
196
          mybank->addr=pci->banks[k].addr;
 
197
          name_found++;
 
198
          break;
 
199
        }
 
200
        k++;
 
201
    }
 
202
    if(name_found==0) {
 
203
      mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC + i;
 
204
      i++;
 
205
    }
 
206
    pci->xml_banks[k]=mynode;
230
207
}
231
208
                  
232
209
        
242
219
pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){
243
220
        pcilib_register_bank_description_t mybank;
244
221
 
245
 
        xmlNodeSetPtr nodesetadress=NULL;
 
222
        xmlNodeSetPtr nodesetaddress=NULL;
246
223
        xmlNodePtr mynode;      
247
224
        xmlXPathContextPtr context;
248
225
        int i;
249
226
 
250
227
        mynode=malloc(sizeof(xmlNode));
251
 
        context=pcilib_xml_getcontext(doc);
252
 
        
 
228
        if(!(context= xmlXPathNewContext(doc))){
 
229
            pcilib_error("can't get an AST from an xml file");
 
230
            return;
 
231
        }
253
232
        /** we get the bank nodes using xpath expression*/
254
 
        nodesetadress=pcilib_xml_getsetproperty(context,BANKS_PATH)->nodesetval;
255
 
        if(nodesetadress->nodeNr==0) return;
 
233
        nodesetaddress=pcilib_xml_get_nodeset_from_xpath(context,BANKS_PATH)->nodesetval;
 
234
        if(!(nodesetaddress)) return;
 
235
        if(nodesetaddress->nodeNr==0) return;
256
236
 
257
 
        pci->banks_xml_nodes=calloc(nodesetadress->nodeNr,sizeof(xmlNodePtr));
258
 
        if(!(pci->banks_xml_nodes)) pcilib_error("can't create bank xml nodes for pcilib_t struct");
 
237
        pci->xml_banks=calloc(PCILIB_MAX_REGISTER_BANKS+1,sizeof(xmlNodePtr));
 
238
        if(!(pci->xml_banks)) pcilib_error("can't create bank xml nodes for pcilib_t struct");
259
239
 
260
240
        /** for each of the bank nodes, we create the associated structure, and  push it in the pcilib environnement*/
261
 
        for(i=0;i<nodesetadress->nodeNr;i++){
262
 
          mynode=nodesetadress->nodeTab[i];
263
 
          pcilib_xml_create_bank(&mybank,mynode,doc);
 
241
        for(i=0;i<nodesetaddress->nodeNr;i++){
 
242
          mynode=nodesetaddress->nodeTab[i];
 
243
          pcilib_xml_create_bank(&mybank,mynode,doc, pci);
264
244
          pcilib_add_register_banks(pci,1,&mybank);
265
 
          pci->banks_xml_nodes[i]=mynode;
266
245
        }
267
246
 
268
247
 
269
248
}
270
249
 
271
250
/** pcilib_xml_registers_compare
272
 
 * function to compare registers by adress for sorting registers
 
251
 * function to compare registers by address for sorting registers
273
252
 * @param a one hypothetic register
274
253
 * @param b one other hypothetic register
 
254
 *@return the result of the comparison
275
255
 */
276
256
static int
277
257
pcilib_xml_compare_registers(void const *a, void const *b){
283
263
 
284
264
 
285
265
/** pcilib_xml_arrange_registers
286
 
 * 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    
 
266
 * 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   
287
267
 * @param[in,out] registers the list of registers in : not ranged out: ranged.
288
268
 * @param[in] size the number of registers. 
289
269
 */
301
281
 * @param[in] doc the AST of the xml file, required for some ibxml2 sub-fonctions
302
282
 * @param[in] mynode the xml node to create register from
303
283
 */
304
 
void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type){
 
284
void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type, pcilib_t* pci){
305
285
                
306
286
    char* ptr;
307
287
    xmlNodePtr cur;
308
 
    xmlChar *value;
309
 
    xmlChar *bank;
 
288
    xmlChar *value=NULL;
 
289
    xmlNodePtr bank=NULL;
310
290
    int i=0;
311
291
 
312
292
    /**we get the children of the register xml nodes, that contains the properties for it*/
317
297
        /* we iterate throug each children to get the associated property
318
298
            note :the use of strtol permits to get as well hexadecimal and decimal values
319
299
                */
320
 
        if(strcmp((char*)cur->name,"adress")==0){       
 
300
        if(strcasecmp((char*)cur->name,"address")==0){  
321
301
                myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0);
322
302
 
323
 
        }else if(strcmp((char*)cur->name,"offset")==0){
 
303
        }else if(strcasecmp((char*)cur->name,"offset")==0){
324
304
                myregister->offset=(pcilib_register_size_t)strtol((char*)value,&ptr,0);
325
305
 
326
 
        }else if(strcmp((char*)cur->name,"size")==0){
 
306
        }else if(strcasecmp((char*)cur->name,"size")==0){
327
307
                myregister->bits=(pcilib_register_size_t)strtol((char*)value,&ptr,0);
328
308
 
329
 
        }else if(strcmp((char*)cur->name,"default")==0){
 
309
        }else if(strcasecmp((char*)cur->name,"default")==0){
330
310
                myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
331
311
 
332
 
        }else if(strcmp((char*)cur->name,"rwmask")==0){
333
 
            if(strcmp((char*)value,"all bits")==0){
 
312
        }else if(strcasecmp((char*)cur->name,"rwmask")==0){
 
313
            if(strcasecmp((char*)value,"all bits")==0){
334
314
              myregister->rwmask=PCILIB_REGISTER_ALL_BITS;
335
 
            }else if(strcmp((char*)value,"0")==0){
 
315
            }else if(strcasecmp((char*)value,"0")==0){
336
316
              myregister->rwmask=0;
337
317
            }else{
338
318
              myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
339
319
            }
340
320
 
341
 
        }else if(strcmp((char*)cur->name,"mode")==0){
342
 
          if(strcmp((char*)value,"R")==0){
 
321
        }else if(strcasecmp((char*)cur->name,"mode")==0){
 
322
          if(strcasecmp((char*)value,"R")==0){
343
323
            myregister->mode=PCILIB_REGISTER_R;
344
 
          }else if(strcmp((char*)value,"W")==0){
 
324
          }else if(strcasecmp((char*)value,"W")==0){
345
325
            myregister->mode=PCILIB_REGISTER_W;
346
 
          }else if(strcmp((char*)value,"RW")==0){
 
326
          }else if(strcasecmp((char*)value,"RW")==0){
347
327
            myregister->mode=PCILIB_REGISTER_RW;
348
 
          }else if(strcmp((char*)value,"W")==0){
 
328
          }else if(strcasecmp((char*)value,"W")==0){
349
329
            myregister->mode=PCILIB_REGISTER_W;
350
 
          }else if(strcmp((char*)value,"RW1C")==0){
 
330
          }else if(strcasecmp((char*)value,"RW1C")==0){
351
331
            myregister->mode=PCILIB_REGISTER_RW1C;
352
 
          }else if(strcmp((char*)value,"W1C")==0){
 
332
          }else if(strcasecmp((char*)value,"W1C")==0){
353
333
            myregister->mode=PCILIB_REGISTER_W1C;
354
334
          }
355
335
 
356
 
        }else if(strcmp((char*)cur->name,"name")==0){
 
336
        }else if(strcasecmp((char*)cur->name,"name")==0){
357
337
          myregister->name=(char*)value;
358
338
 
359
 
        }else if(strcmp((char*)cur->name,"value_min")==0){
 
339
        }else if(strcasecmp((char*)cur->name,"value_min")==0){
360
340
          /* not implemented yet*/        //      myregister->value_min=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
361
341
 
362
 
        }else if(strcmp((char*)cur->name,"value_max")==0){
 
342
        }else if(strcasecmp((char*)cur->name,"value_max")==0){
363
343
          /* not implemented yet*/        //      myregister->value_max=(pcilib_register_value_t)strtol((char*)value,&ptr,0);   
364
344
 
365
 
        }else if(strcmp((char*)cur->name,"description")==0){
 
345
        }else if(strcasecmp((char*)cur->name,"description")==0){
366
346
          i++;
367
347
          myregister->description=(char*)value;
368
348
        }
375
355
    
376
356
 
377
357
    /** we then get properties that can not be parsed as the previous ones*/
378
 
        if(strcmp((char*)type,"standard")==0){
 
358
        if(strcasecmp((char*)type,"standard")==0){
379
359
          myregister->type=PCILIB_REGISTER_STANDARD;
380
 
          bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent))->xmlChildrenNode,1);   /**<we get the bank adress node*/
381
 
 
382
 
        }else if(strcmp((char*)type,"bits")==0){
 
360
          bank=pcilib_xml_get_bank_node_from_register_node(mynode);
 
361
          while(bank!=NULL){
 
362
            value=xmlNodeListGetString(doc,bank->children,1);
 
363
            if(strcasecmp((char*)bank->name,"name")==0){
 
364
              break;
 
365
            }
 
366
            bank=bank->next;
 
367
          }
 
368
 
 
369
          int k=0;
 
370
 
 
371
          while(pci->banks[k].name!=NULL){
 
372
            printf("name %s\n",pci->banks[k].name);
 
373
            if(strcasecmp(pci->banks[k].name,(char*)value)==0){
 
374
              myregister->bank=pci->banks[k].addr;
 
375
              printf("ok\n");
 
376
              break;
 
377
            }
 
378
            k++;
 
379
          }
 
380
 
 
381
        }else if(strcasecmp((char*)type,"bits")==0){
383
382
          myregister->type=PCILIB_REGISTER_BITS;
384
 
          bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent->parent->parent))->xmlChildrenNode,1);/**<we get the bank adress node*/
385
 
 
386
 
          /* we then get the properties from the parent standard regsiter, and that are not present for the bit register*/
387
 
          cur=mynode->parent->parent->children; /**<get the parent standard register*/
388
 
          while(cur!=NULL){
389
 
            value=xmlNodeListGetString(doc,cur->children,1);
390
 
            if(strcmp((char*)cur->name,"adress")==0){   
391
 
              myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0);
392
 
            }else if(strcmp((char*)cur->name,"default")==0){
393
 
              myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
394
 
            }else if(strcmp((char*)cur->name,"rwmask")==0){
395
 
              if(strcmp((char*)value,"all bits")==0){
396
 
                myregister->rwmask=PCILIB_REGISTER_ALL_BITS;
397
 
              }else if(strcmp((char*)value,"0")==0){
398
 
                myregister->rwmask=0;
399
 
              }else{
400
 
                myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0);
401
 
              }
402
 
            }
403
 
            cur=cur->next;
404
 
          }
405
 
 
406
 
        }else if(strcmp((char*)type,"fifo")==0){
 
383
 
 
384
        }else if(strcasecmp((char*)type,"fifo")==0){
407
385
  /* not implemented yet*/        myregister->type=PCILIB_REGISTER_FIFO;
408
386
        }
409
 
 
410
 
        if(strcmp((char*)bank,"bank 0")==0){
411
 
          myregister->bank=PCILIB_REGISTER_BANK0;
412
 
        }else if(strcmp((char*)bank,"bank 1")==0){
413
 
          myregister->bank=PCILIB_REGISTER_BANK1;
414
 
        }else if(strcmp((char*)bank,"bank 2")==0){
415
 
          myregister->bank=PCILIB_REGISTER_BANK2;
416
 
        }else if(strcmp((char*)bank,"bank 3")==0){
417
 
          myregister->bank=PCILIB_REGISTER_BANK3;
418
 
        }else if(strcmp((char*)bank,"DMA bank")==0){
419
 
          myregister->bank=PCILIB_REGISTER_BANK_DMA;
420
 
        }else if (strcmp((char*)bank,"dynamic bank")==0){
421
 
          myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC;
422
 
        }else{
423
 
          myregister->bank=PCILIB_REGISTER_BANK_INVALID;
424
 
        }
 
387
      
 
388
        
425
389
}       
426
390
 
427
391
/** pcilib_xml_initialize_registers
428
392
 *
429
393
 * this function create a list of registers from an abstract syntax tree
430
394
 *
431
 
 * 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)
 
395
 * 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)
432
396
 * @param[in] doc the xpath context of the xml file.
433
397
 * @param[in] pci the pcilib_t struct running, that will get filled
434
398
 */
435
399
void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){
436
400
        
437
 
  xmlNodeSetPtr nodesetadress=NULL, nodesetsubadress=NULL;
438
 
        xmlChar *type=NULL;
 
401
  xmlNodeSetPtr nodesetaddress=NULL, nodesetsubaddress=NULL;
439
402
        xmlNodePtr mynode;      
440
403
        xmlXPathContextPtr context;
441
404
        pcilib_register_description_t *registers=NULL;
442
405
        pcilib_register_description_t myregister;
443
406
        int i,j;
444
407
 
445
 
        context=pcilib_xml_getcontext(doc);
 
408
        context= xmlXPathNewContext(doc);
 
409
        if(!(context= xmlXPathNewContext(doc))){
 
410
            pcilib_error("can't get an AST from an xml file");
 
411
            return;
 
412
        }
446
413
        
447
414
        /** we first get the nodes of standard and bits registers*/
448
 
        nodesetadress=pcilib_xml_getsetproperty(context,REGISTERS_PATH)->nodesetval;
449
 
        nodesetsubadress=pcilib_xml_getsetproperty(context,BITS_REGISTERS_PATH)->nodesetval;
450
 
        if(nodesetadress->nodeNr>0)registers=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(pcilib_register_description_t));
 
415
        nodesetaddress=pcilib_xml_get_nodeset_from_xpath(context,REGISTERS_PATH)->nodesetval;
 
416
        nodesetsubaddress=pcilib_xml_get_nodeset_from_xpath(context,BITS_REGISTERS_PATH)->nodesetval;
 
417
        if(!(nodesetaddress)) return;
 
418
        if(nodesetaddress->nodeNr>0)registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(pcilib_register_description_t));
451
419
        else return;
452
420
        
453
 
        pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(xmlNodePtr));
454
 
        if(!(pci->registers_xml_nodes)) pcilib_warning("can't create registers xml nodes in pcilib_t struct");
 
421
        pci->xml_registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(xmlNodePtr));
 
422
        if(!(pci->xml_registers)) pcilib_warning("can't create registers xml nodes in pcilib_t struct");
455
423
                
456
424
        /** we then iterate through standard registers nodes to create registers structures*/
457
 
        for(i=0;i<nodesetadress->nodeNr;i++){
458
 
                type=(xmlChar*)"standard";
459
 
                mynode=nodesetadress->nodeTab[i];
460
 
                pcilib_xml_create_register(&myregister,mynode,doc,type);
 
425
        for(i=0;i<nodesetaddress->nodeNr;i++){
 
426
                mynode=nodesetaddress->nodeTab[i];
 
427
                pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"standard",pci);
461
428
                registers[i]=myregister;
462
 
                pci->registers_xml_nodes[i]=mynode;
 
429
                pci->xml_registers[i]=mynode;
463
430
        }
464
431
        
465
432
        j=i;
 
433
        if(!(nodesetsubaddress)) return;
466
434
        /** we then iterate through bits  registers nodes to create registers structures*/
467
 
        for(i=0;i<nodesetsubadress->nodeNr;i++){
468
 
                type=(xmlChar*)"bits";
469
 
                mynode=nodesetsubadress->nodeTab[i];
470
 
                pcilib_xml_create_register(&myregister,mynode,doc,type);
 
435
        for(i=0;i<nodesetsubaddress->nodeNr;i++){
 
436
                mynode=nodesetsubaddress->nodeTab[i];
 
437
                pcilib_xml_create_register(&myregister,mynode->parent->parent,doc,(xmlChar*)"standard",pci);
 
438
                pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"bits",pci);
471
439
                registers[i+j]=myregister;
472
 
                pci->registers_xml_nodes[i+j]=mynode;
 
440
                pci->xml_registers[i+j]=mynode;
473
441
        }
474
442
        
475
443
        /**we arrange the register for them to be well placed for pci-l*/
476
 
        pcilib_xml_arrange_registers(registers,nodesetadress->nodeNr+nodesetsubadress->nodeNr);
 
444
        pcilib_xml_arrange_registers(registers,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr);
477
445
        /**we fille the pcilib_t struct*/
478
 
        pcilib_add_registers(pci,nodesetadress->nodeNr+nodesetsubadress->nodeNr,registers);
 
446
        pcilib_add_registers(pci,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,registers);
479
447
}
480
448
 
481
449
 
482
450
/** pcilib_init_xml
483
451
 * this function will initialize the registers and banks from the xml files
484
452
 * @param[in,out] ctx the pciilib_t running that gets filled with structures
 
453
 * @param[in] model the current model of ctx
 
454
 * @return an error code
485
455
 */
486
456
 
487
 
int pcilib_init_xml(pcilib_t* ctx){
 
457
int pcilib_init_xml(pcilib_t* ctx, char* model){
488
458
    char *path,*pwd, **line, *line_xsd=NULL;
489
459
    int i=1,k;
490
460
    xmlDocPtr* docs;
504
474
    }
505
475
    
506
476
    /** we then open the directory corresponding to the ctx model*/
507
 
    pwd=malloc((strlen(path)+strlen(ctx->model))*sizeof(char));
508
 
    sprintf(pwd,"%s%s/",path,ctx->model);
 
477
    pwd=malloc((strlen(path)+strlen(model))*sizeof(char));
 
478
    sprintf(pwd,"%s%s/",path,model);
509
479
    if((rep=opendir(pwd))==NULL){
510
480
      pcilib_warning("could not open the directory for xml files: error %i\n",errno);
511
481
      return 1;
538
508
    /** for each xml file, we validate it, and get the registers and the banks*/
539
509
    docs=malloc((i-1)*sizeof(xmlDocPtr));
540
510
    for(k=0;k<i-1;k++){
541
 
      err=validation(line[k],line_xsd);
542
 
      if(err==0){
543
 
        docs[k]=pcilib_xml_getdoc(line[k]);
544
 
        pcilib_xml_initialize_banks(ctx,docs[k]);
545
 
        pcilib_xml_initialize_registers(ctx,docs[k]);
 
511
      if((err=pcilib_xml_validate(line[k],line_xsd))==0){
 
512
        if((docs[k]=xmlParseFile(line[k]))){
 
513
          pcilib_xml_initialize_banks(ctx,docs[k]);
 
514
            pcilib_xml_initialize_registers(ctx,docs[k]);
 
515
        }
 
516
        else pcilib_error("xml document %s not parsed successdfullly\n",line[k]);
546
517
      }
547
518
    }  
548
 
    
549
 
    //    free(path);
 
519
    ctx->xml_context=malloc(sizeof(pcilib_xml_context_t));
 
520
    ctx->xml_context->docs=malloc(sizeof(xmlDocPtr)*(i-1));
 
521
    ctx->xml_context->docs=docs;
 
522
 
550
523
    free(pwd);
551
524
    free(line);
552
525
    free(line_xsd);
553
 
    free(docs);
554
 
 
555
 
    xmlCleanupParser();
556
 
    xmlMemoryDump();
557
526
 
558
527
    return 0;
559
528
}  
560
529
 
 
530
/** pcilib_clean_xml
 
531
 * this function free the xml parts of the pcilib_t running, and some libxml ashes
 
532
 * @param[in] pci the pcilib_t running
 
533
*/
 
534
void pcilib_clean_xml(pcilib_t* pci){
 
535
 
 
536
  free(pci->xml_banks);
 
537
  free(pci->xml_registers);
 
538
  free(pci->xml_context);
 
539
  xmlCleanupParser();
 
540
  xmlMemoryDump();
 
541
 
 
542
}