source: soft/giet_vm/xml/xml_parser.c @ 257

Last change on this file since 257 was 255, checked in by meunier, 11 years ago
  • Added a syscall and some user functions to manipulate the Simulation Helper
  • Changed the the way the Vseg -> Pseg mapping is made during the boot to better utilize the address space (+ adaptation of the algorithm in memo)
  • Fixed a bug in boot_init (vobj_init): the vobj initialization could only be made for the first application (ptpr was not changed)
File size: 75.8 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////////
2// File     : xml_parser.c
3// Date     : 14/04/2012
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////////
7// This program translate a "map.xml" source file to a binary file "map.bin" that
8// can be directly loaded in memory and used by the GIET-VM operating system.
9//
10// This map.xml file contains :
11// 1) the multi-cluster/multi-processors hardware architecture description
12// 2) the various multi-threaded software applications
13// 3) the mapping directives bor both the tasks and the virtual segments.
14// The corresponding C structures are defined in the "mapping_info.h" file.
15//
16// This parser also generates the "hard_config.h" and the "giet_vsegs.ld" files,
17// required  to compile the GIET-VM code.
18///////////////////////////////////////////////////////////////////////////////////////
19
20#include  <stdlib.h>
21#include  <fcntl.h>
22#include  <sys/types.h>
23#include  <sys/stat.h>
24#include  <unistd.h>
25#include  <stdio.h>
26#include  <string.h>
27#include  <assert.h>
28#include  <libxml/xmlreader.h>
29#include  <mapping_info.h>
30#include  <irq_handler.h>
31
32#define MAX_CLUSTERS   1024
33#define MAX_PSEGS      4096
34#define MAX_VSPACES    1024
35#define MAX_TASKS      4096
36#define MAX_MWMRS      4096
37#define MAX_VSEGS      4096
38#define MAX_VOBJS      8192
39#define MAX_PROCS      1024
40#define MAX_IRQS       8192
41#define MAX_COPROCS    4096
42#define MAX_CP_PORTS   8192
43#define MAX_PERIPHS    8192
44
45#define XML_PARSER_DEBUG  0
46
47///////////////////////////////////////////////////////////////////////////////////
48//     global variables used to store and index the data structures
49///////////////////////////////////////////////////////////////////////////////////
50
51mapping_header_t *   header;
52mapping_cluster_t *  cluster[MAX_CLUSTERS];  // cluster array
53mapping_pseg_t *     pseg[MAX_PSEGS];        // pseg array
54mapping_vspace_t *   vspace[MAX_VSPACES];    // vspace array
55mapping_vseg_t *     vseg[MAX_VSEGS];        // vseg array
56mapping_vobj_t *     vobj[MAX_VOBJS];        // vobj array
57mapping_task_t *     task[MAX_TASKS];        // task array
58mapping_proc_t *     proc[MAX_PROCS];        // proc array
59mapping_irq_t *      irq[MAX_IRQS];          // irq array
60mapping_coproc_t *   coproc[MAX_COPROCS];    // coproc array
61mapping_cp_port_t *  cp_port[MAX_CP_PORTS];  // coproc port array
62mapping_periph_t *   periph[MAX_PERIPHS];    // peripheral array
63
64// Index for the various arrays
65
66unsigned int cluster_index  = 0;
67unsigned int vspace_index = 0;
68unsigned int global_index = 0;
69unsigned int pseg_index = 0;       
70
71unsigned int proc_index = 0;
72unsigned int proc_loc_index = 0;
73
74unsigned int irq_index = 0;
75unsigned int irq_loc_index  = 0;
76
77unsigned int coproc_index = 0;
78unsigned int coproc_loc_index = 0;
79
80unsigned int cp_port_index = 0;
81unsigned int cp_port_loc_index = 0;
82
83unsigned int periph_index = 0;
84unsigned int periph_loc_index = 0;
85
86unsigned int vseg_index = 0;
87unsigned int vseg_loc_index = 0;
88
89unsigned int task_index = 0;
90unsigned int task_loc_index = 0;
91
92unsigned int vobj_index = 0;
93unsigned int vobj_loc_index = 0;
94unsigned int vobj_count = 0;
95
96
97//////////////////////////////
98// for replicated peripheral
99//////////////////////////////
100char found_timer = 0;
101char found_icu   = 0;
102char found_xcu   = 0;
103char found_dma   = 0;
104char found_mmc   = 0;
105
106
107////////////////////////////////////////////////////////////////////
108// These variables are used to generate the hard_config.h file
109////////////////////////////////////////////////////////////////////
110
111unsigned int cluster_y        = 0; // number of clusters in a column
112unsigned int cluster_x        = 0; // number of clusters in a row
113unsigned int nb_proc_max      = 0; // max number of processors per cluster
114unsigned int nb_tasks_max     = 0; // max number of tasks (for all vspaces)
115
116unsigned int tim_channels     = 0; // max number of user timers per cluster
117unsigned int dma_channels     = 0; // max number of DMA channels per cluster
118
119unsigned int tty_channels     = 0; // total number of terminals in first TTY
120unsigned int ioc_channels     = 0; // total number of channels in first IOC
121unsigned int nic_channels     = 0; // total number of channels in first NIC
122unsigned int cma_channels     = 0; // total number of channels in first CMA
123
124unsigned int use_iob          = 0; // using IOB component
125unsigned int use_xcu          = 0; // using XCU (not ICU)
126
127
128////////////////////////////////////////////////////////////////
129// These variables are used to generate the giet_vseg.ld file
130////////////////////////////////////////////////////////////////
131
132unsigned int periph_vbase_array[PERIPH_TYPE_MAX_VALUE] 
133         = { [0 ... (PERIPH_TYPE_MAX_VALUE - 1)] = 0xFFF00000 };
134
135//////////////////////////////////////////////////////////////////////
136// This arrray is useful to build a temporary list of vobj references.
137// The struct vobj_ref_s is formed by a vspace_name and a vobj_name.
138// This array is used to set the attribute vobj_id of a cp_port
139// once all the vspace have been parsed.
140/////////////////////////////////////////////////////////////////////
141typedef struct vobj_ref_s
142{
143    char vspace_name[32];
144    char vobj_name[32];
145} vobj_ref_t;
146
147vobj_ref_t * cp_port_vobj_ref[MAX_CP_PORTS];   
148
149
150//////////////////////////////////////////////////
151unsigned int getIntValue( xmlTextReaderPtr reader, 
152                          const char * attributeName, 
153                          unsigned int * ok) 
154{
155    unsigned int value = 0;
156    unsigned int i;
157    char c;
158
159    char * string = (char *) xmlTextReaderGetAttribute(reader, 
160                                (const xmlChar *) attributeName);
161
162    if (string == NULL) 
163    {
164        // missing argument
165        *ok = 0;
166        return 0;
167    }
168    else 
169    {
170        if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) 
171        {
172            // Hexa
173            for (i = 2 ; (string[i] != 0) && (i < 10) ; i++) 
174            {
175                c = string[i];
176                if      ((c >= '0') && (c <= '9')) { value = (value << 4) + string[i] - 48; }
177                else if ((c >= 'a') && (c <= 'f')) { value = (value << 4) + string[i] - 87; }
178                else if ((c >= 'A') && (c <= 'F')) { value = (value << 4) + string[i] - 55; }
179                else 
180                {
181                    *ok = 0;
182                    return 0;
183                }
184            }
185        }
186        else 
187        {
188            // Decimal
189            for (i = 0; (string[i] != 0) && (i < 9); i++) 
190            {
191                c = string[i];
192                if ((c >= '0') && (c <= '9')) value = (value * 10) + string[i] - 48;
193                else 
194                {
195                    *ok = 0;
196                    return 0;
197                }
198            }
199        }
200        *ok = 1;
201        return value; 
202    }
203} // end getIntValue()
204
205////////////////////////////////////////////////
206paddr_t getPaddrValue( xmlTextReaderPtr reader, 
207                       const char * attributeName, 
208                       unsigned int * ok) 
209{
210    paddr_t value = 0;
211    unsigned int i;
212    char c;
213
214    char * string = (char *) xmlTextReaderGetAttribute(reader, 
215                                (const xmlChar *) attributeName);
216
217    if (string == NULL) 
218    {
219        // missing argument
220        *ok = 0;
221        return 0;
222    }
223    else 
224    {
225        if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) 
226        {
227            // Hexa
228            for (i = 2 ; (string[i] != 0) && (i < 18) ; i++) 
229            {
230                c = string[i];
231                if      ((c >= '0') && (c <= '9')) { value = (value << 4) + string[i] - 48; }
232                else if ((c >= 'a') && (c <= 'f')) { value = (value << 4) + string[i] - 87; }
233                else if ((c >= 'A') && (c <= 'F')) { value = (value << 4) + string[i] - 55; }
234                else 
235                {
236                    *ok = 0;
237                    return 0;
238                }
239            }
240        }
241        else 
242        {
243            // Decimal not supported for paddr_t
244            *ok = 0;
245            return 0;
246        }
247        *ok = 1;
248        return value; 
249    }
250} // end getPaddrValue()
251
252////////////////////////////////////////////////
253char * getStringValue( xmlTextReaderPtr reader, 
254                       const char * attributeName, 
255                       unsigned int * ok ) 
256{
257    char * string = (char *) xmlTextReaderGetAttribute(reader, 
258                               (const xmlChar *) attributeName);
259
260
261    if (string == NULL) 
262    {
263        // missing argument
264        *ok = 0;
265        return NULL;
266    }
267    else 
268    {
269        //we read only string smaller than 32 byte
270        if (strlen(string) > 32) 
271        {
272            printf("[XML ERROR] all strings must be less than 32 bytes\n");
273            exit(1);
274        }
275
276        *ok = 1;
277        return string;
278    }
279} // end getStringValue()
280
281///////////////////////////////////////////////////////////////////////////////////
282// This function set the vbase address for all peripheral types.
283// For replicated peripherals with the same type the virtual base address must be:
284//   vbase = seg_type_base & 0XFFF00000 +
285//          (cluster_id * vbase_cluster_increment) & 0x000FFFFF
286void set_periph_vbase_array()
287{
288    unsigned int vseg_id;      // vseg global index
289    unsigned int periph_id;    // periph global index
290    unsigned int pseg_id;      // pseg global index
291    unsigned int cluster_id;   // cluster global index
292    unsigned int type;         // peripheral type
293
294    unsigned int msb_mask = 0xFFF00000;
295    unsigned int lsb_mask = 0x000FFFFF;
296
297    // We are looking for any vseg matching a peripheral
298    // (i.e. they are associated to the same pseg)
299
300    // scan all vsegs
301    for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++)
302    {
303        // keep only vseg corresponding to a periph       
304        if ( vobj[vseg[vseg_id]->vobj_offset]->type == VOBJ_TYPE_PERI )
305        {
306            pseg_id = vseg[vseg_id]->psegid; 
307            cluster_id = pseg[pseg_id]->cluster;
308
309            // scan all periphs
310            for ( periph_id = 0 ; periph_id < header->periphs ; periph_id++)
311            {
312                if( periph[periph_id]->psegid == pseg_id ) // matching !!!
313                {
314                    type = periph[periph_id]->type;
315                    if ( periph_vbase_array[type] == 0xFFF00000 )  // vbase not set
316                    {
317                        periph_vbase_array[type] = vseg[vseg_id]->vbase;   
318                    }
319                    else                                 // vbase already set
320                    {
321                        // checking 12 MSB bits for replicated peripherals
322                        if( (vseg[vseg_id]->vbase & msb_mask) != 
323                            (periph_vbase_array[type] & msb_mask) )
324                        {
325                            printf("[XML ERROR] All peripherals with same type ");
326                            printf(" should share the same 12 MSB for vbase address\n");
327                            printf("periph index = %d / periph type = %d / vbase = %x\n",
328                                    periph_id, type, vseg[vseg_id]->vbase);
329                            exit(1);
330                        }
331                        // checking 20 LSB bits for replicated peripherals
332                        if( (vseg[vseg_id]->vbase & lsb_mask) != 
333                            (header->increment * cluster_id) )
334                        {
335                            printf("[XML ERROR] All peripherals with same type ");
336                            printf(" must have the 20 LSB bits = cluster_id * increment");
337                            printf("periph index = %d / periph type = %d / vbase = %x\n",
338                                    periph_id, type, vseg[vseg_id]->vbase);
339                            exit(1);
340                        }
341                    }
342                }
343            }
344        }   
345    }
346}  // end set_periph_vbase_array()
347
348////////////////////////////////////////////////////////
349int getPsegId(unsigned int cluster_id, char * pseg_name) 
350{
351    unsigned int pseg_id;
352    unsigned int pseg_min = cluster[cluster_id]->pseg_offset;
353    unsigned int pseg_max = pseg_min + cluster[cluster_id]->psegs;
354
355    for (pseg_id = pseg_min; pseg_id < pseg_max; pseg_id++) 
356    {
357        if (strcmp(pseg[pseg_id]->name, pseg_name) == 0) 
358        {
359            return pseg_id;
360        }
361    }
362    return -1;
363}
364
365///////////////////////////////////
366int getVspaceId(char * vspace_name) 
367{
368    unsigned int vspace_id;
369
370    for (vspace_id = 0; vspace_id < vspace_index; vspace_id++) 
371    {
372        if (strcmp(vspace[vspace_id]->name, vspace_name) == 0) 
373        {
374            return vspace_id;
375        }
376    }
377    return -1;
378}
379
380///////////////////////////////////////////////////////////////////////////////////
381int getVobjLocId(unsigned int vspace_id, char * vobj_name, unsigned int vspace_max) 
382{
383    unsigned int vobj_id;
384    unsigned int vobj_min = vspace[vspace_id]->vobj_offset;
385    unsigned int vobj_max = vobj_min + vspace_max;
386
387    for (vobj_id = vobj_min; vobj_id < vobj_max; vobj_id++) 
388    {
389        if (strcmp(vobj[vobj_id]->name, vobj_name) == 0) return (vobj_id - vobj_min);
390    }
391    return -1;
392}
393
394//////////////////////////////////////
395void taskNode(xmlTextReaderPtr reader) 
396{
397    unsigned int ok;
398    unsigned int value;
399    char * str;
400
401    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
402
403    if (task_index >= MAX_TASKS) 
404    {
405        printf("[XML ERROR] The number of tasks is larger than %d\n", MAX_TASKS);
406        exit(1);
407    }
408
409#if XML_PARSER_DEBUG
410printf("   task %d\n", task_loc_index);
411#endif
412
413    task[task_index] = (mapping_task_t *) malloc(sizeof(mapping_task_t));
414
415    ////////// get name attribute
416    str = getStringValue(reader, "name", &ok);
417    if (ok) 
418    {
419#if XML_PARSER_DEBUG
420printf("      name = %s\n", str);
421#endif
422        strncpy( task[task_index]->name, str, 31 );
423    }
424    else 
425    {
426        printf("[XML ERROR] illegal or missing <name> attribute for task (%d,%d)\n", 
427                vspace_index, task_loc_index);
428        exit(1);
429    }
430
431    ///////// get clusterid attribute
432    value = getIntValue(reader, "clusterid", &ok);
433    if (ok) 
434    {
435#if XML_PARSER_DEBUG
436printf("      clusterid = %x\n", value);
437#endif
438        if (value >= header->clusters) 
439        {
440            printf("[XML ERROR] <clusterid> too large for task (%d,%d)\n",
441                    vspace_index, task_loc_index);
442            exit(1);
443        }
444        task[task_index]->clusterid = value;
445    } 
446    else 
447    {
448        printf("[XML ERROR] illegal or missing <clusterid> attribute for task (%d,%d)\n",
449                vspace_index, task_loc_index);
450        exit(1);
451    }
452
453    ////////// get proclocid attribute
454    value = getIntValue(reader, "proclocid", &ok);
455    if (ok) 
456    {
457#if XML_PARSER_DEBUG
458printf("      proclocid = %x\n", value);
459#endif
460        if (value >= cluster[task[task_index]->clusterid]->procs) 
461        {
462            printf("[XML ERROR] <proclocid> too large for task (%d,%d)\n",
463                    vspace_index, task_loc_index);
464            exit(1);
465        }
466        task[task_index]->proclocid = value;
467    } 
468    else 
469    {
470        printf("[XML ERROR] illegal or missing <locprocid> attribute for task (%d,%d)\n", 
471                vspace_index, task_loc_index);
472        exit(1);
473    }
474
475    ////////// get stackname attribute
476    str = getStringValue(reader, "stackname" , &ok);
477    if (ok) 
478    {
479        int index = getVobjLocId(vspace_index, str , vobj_loc_index);
480        if (index >= 0) 
481        {
482#if XML_PARSER_DEBUG
483printf("      stackname = %s\n", str);
484printf("      stackid   = %d\n", index);
485#endif
486            task[task_index]->stack_vobjid = index;
487        }
488        else 
489        {
490            printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n", 
491                    vspace_index, task_loc_index);
492            exit(1);
493        }
494    } 
495    else 
496    {
497        printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n", 
498                vspace_index, task_loc_index);
499        exit(1);
500    }
501
502    ////////// get heap attribute
503    str = getStringValue(reader, "heapname", &ok);
504    if (ok) 
505    {
506        int index = getVobjLocId(vspace_index, str, vobj_loc_index);
507        if (index >= 0) 
508        {
509#if XML_PARSER_DEBUG
510printf("      heapname = %s\n", str);
511printf("      heapid   = %d\n", index);
512#endif
513            task[task_index]->heap_vobjid = index;
514        }
515        else 
516        {
517            printf("[XML ERROR] illegal or missing <heapname> for task (%d,%d)\n", 
518                   vspace_index, task_loc_index);
519            exit(1);
520        }
521    } 
522    else 
523    {
524        task[task_index]->heap_vobjid = -1;
525    }
526
527
528    ////////// get startid  attribute
529    value = getIntValue(reader, "startid", &ok);
530    if (ok) 
531    {
532#if XML_PARSER_DEBUG
533printf("      startid = %x\n", value);
534#endif
535        task[task_index]->startid = value;
536    } 
537    else 
538    {
539        printf("[XML ERROR] illegal or missing <startid> attribute for task (%d,%d)\n", 
540                vspace_index, task_loc_index);
541        exit(1);
542    }
543
544    /////////// get usetty  attribute (optionnal : 0 if missing)
545    value = getIntValue(reader, "usetty", &ok);
546#if XML_PARSER_DEBUG
547printf("      usetty = %x\n", value);
548#endif
549    task[task_index]->use_tty = (ok)? value : 0;
550
551    /////////// get usenic  attribute (optionnal : 0 if missing)
552    value = getIntValue(reader, "usenic", &ok);
553#if XML_PARSER_DEBUG
554printf("      usenic = %x\n", value);
555#endif
556    task[task_index]->use_nic = (ok)? value : 0;
557
558    /////////// get usetim attribute (optionnal : 0 if missing)
559    value = getIntValue(reader, "usetim", &ok);
560#if XML_PARSER_DEBUG
561printf("      usetim = %x\n", value);
562#endif
563    task[task_index]->use_tim = (ok)? value : 0;
564
565    /////////// get usedma  attribute (optionnal : 0 if missing)
566    value = getIntValue(reader, "usedma", &ok);
567#if XML_PARSER_DEBUG
568printf("      usedma = %x\n", value);
569#endif
570    task[task_index]->use_dma = (ok)? value : 0;
571
572    /////////// get useioc  attribute (optionnal : 0 if missing)
573    value = getIntValue(reader, "useioc", &ok);
574#if XML_PARSER_DEBUG
575printf("      useioc = %x\n", value);
576#endif
577    task[task_index]->use_ioc = (ok)? value : 0;
578
579    /////////// get usecma  attribute (optionnal : 0 if missing)
580    value = getIntValue(reader, "usecma", &ok);
581#if XML_PARSER_DEBUG
582printf("      usecma = %x\n", value);
583#endif
584    task[task_index]->use_cma = (ok)? value : 0;
585
586    task_index++;
587    task_loc_index++;
588} // end taskNode()
589
590//////////////////////////////////////
591void vobjNode(xmlTextReaderPtr reader) 
592{
593    unsigned int ok;
594    unsigned int value;
595    char * str;
596
597    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
598
599    if (vobj_index >= MAX_VOBJS) 
600    {
601        printf("[XML ERROR] The number of vobjs is larger than %d\n", MAX_VOBJS);
602        exit(1);
603    }
604
605#if XML_PARSER_DEBUG
606printf("      vobj %d\n", vobj_loc_index);
607#endif
608
609    vobj[vobj_index] = (mapping_vobj_t *) malloc(sizeof(mapping_vobj_t));
610
611    ///////// get name attribute
612    str = getStringValue(reader, "name", &ok);
613    if (ok) 
614    {
615#if XML_PARSER_DEBUG
616printf("        name = %s\n", str);
617#endif
618        strncpy(vobj[vobj_index]->name, str, 31);
619    }
620    else 
621    {
622        printf("[XML ERROR] illegal or missing <name> attribute for vobj (%d,%d)\n", 
623                vseg_index, vobj_loc_index);
624        exit(1);
625    }
626
627    //////// get type attribute
628    str = getStringValue(reader, "type", &ok);
629#if XML_PARSER_DEBUG
630printf("        type = %s\n", str);
631#endif
632
633    if      (ok && (strcmp(str, "ELF")      == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_ELF;      }
634    else if (ok && (strcmp(str, "PERI")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PERI;     }
635    else if (ok && (strcmp(str, "BLOB")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BLOB;     }
636    else if (ok && (strcmp(str, "PTAB")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PTAB;     }
637    else if (ok && (strcmp(str, "MWMR")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MWMR;     }
638    else if (ok && (strcmp(str, "LOCK")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_LOCK;     }
639    else if (ok && (strcmp(str, "BUFFER")   == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BUFFER;   }
640    else if (ok && (strcmp(str, "BARRIER")  == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BARRIER;  }
641    else if (ok && (strcmp(str, "CONST")    == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_CONST;    }
642    else if (ok && (strcmp(str, "MEMSPACE") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MEMSPACE; }
643    else if (ok && (strcmp(str, "SCHED")    == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_SCHED;    }
644    else 
645    {
646        printf("[XML ERROR] illegal or missing <type> attribute for vobj (%d,%d)\n", 
647                vspace_index, vobj_loc_index);
648        exit(1);
649    }
650    // some more checking
651    if ( (vobj[vobj_index]->type == VOBJ_TYPE_ELF) ||
652         (vobj[vobj_index]->type == VOBJ_TYPE_PERI) )
653    {
654        assert( (vobj_count == 0) && 
655        "[XML ERROR] an ELF or PERI vobj must be alone in a vseg");
656    }
657       
658
659    ////////// get length attribute
660    value = getIntValue(reader, "length", &ok);
661    if (ok) {
662#if XML_PARSER_DEBUG
663printf("        length = %d\n", value);
664#endif
665        vobj[vobj_index]->length = value;
666    } 
667    else {
668        printf("[XML ERROR] illegal or missing <length> attribute for vobj (%d,%d)\n", 
669                vspace_index, vobj_loc_index);
670        exit(1);
671    }
672
673    ////////// get align attribute (optional : 0 if missing)
674    value = getIntValue(reader, "align", &ok);
675    if (ok) {
676#if XML_PARSER_DEBUG
677printf("        align = %d\n", value);
678#endif
679        vobj[vobj_index]->align = value;
680    } 
681    else {
682        vobj[vobj_index]->align = 0;
683    }
684
685    ////////// get binpath attribute (optional : '\0' if missing)
686    str = getStringValue(reader, "binpath", &ok);
687    if (ok) {
688#if XML_PARSER_DEBUG
689printf("        binpath = %s\n", str);
690#endif
691        strncpy(vobj[vobj_index]->binpath, str, 63);
692    } 
693    else {
694        vobj[vobj_index]->binpath[0] = '\0';
695    }
696
697    ////////// get init attribute (mandatory for mwmr and barrier)
698    value = getIntValue(reader, "init", &ok);
699    if (ok) 
700    {
701#if XML_PARSER_DEBUG
702printf("        init  = %d\n", value);
703#endif
704        vobj[vobj_index]->init = value;
705    } 
706    else 
707    {
708        if ((vobj[vobj_index]->type == VOBJ_TYPE_MWMR) || 
709            (vobj[vobj_index]->type == VOBJ_TYPE_BARRIER) ||
710            (vobj[vobj_index]->type == VOBJ_TYPE_CONST)) 
711        {
712            printf("[XML ERROR] illegal or missing <value> attribute for vobj (%d,%d). \
713                    All MWMR or BARRIER or CONST vobj must have a init value \n", 
714                    vspace_index, vobj_loc_index);
715            exit(1);
716        }
717        vobj[vobj_index]->init = 0;
718    }
719
720    vobj_index++;
721    vobj_count++;
722    vobj_loc_index++;
723} // end vobjNode()
724
725//////////////////////////////////////
726void vsegNode(xmlTextReaderPtr reader) 
727{
728    unsigned int ok;
729    unsigned int value;
730    char * str;
731
732    vobj_count = 0;
733
734    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
735
736    if (vseg_index >= MAX_VSEGS) 
737    {
738        printf("[XML ERROR] The number of vsegs is larger than %d\n", MAX_VSEGS);
739        exit(1);
740    }
741
742#if XML_PARSER_DEBUG
743printf("    vseg %d\n", vseg_loc_index);
744#endif
745
746    vseg[vseg_index] = (mapping_vseg_t *) malloc(sizeof(mapping_vseg_t));
747
748    ////////// set vobj_offset attributes
749    vseg[vseg_index]->vobj_offset = vobj_index;
750    // Init pbase_set to false
751    vseg[vseg_index]->pbase_set = 0;
752
753#if XML_PARSER_DEBUG
754printf("      vobj_offset = %d\n", vobj_index);
755#endif
756
757    ///////// get name attribute
758    str = getStringValue(reader, "name", &ok);
759    if (ok) 
760    {
761#if XML_PARSER_DEBUG
762printf("      name = %s\n", str);
763#endif
764        strncpy( vseg[vseg_index]->name, str, 31);
765    }
766    else 
767    {
768        printf("[XML ERROR] illegal or missing <name> attribute for vseg (%d,%d)\n", 
769                vspace_index, vseg_loc_index);
770        exit(1);
771    }
772
773    ////////// get ident attribute (optional : 0 if missing)
774    value = getIntValue(reader, "ident", &ok);
775    if (ok) 
776    {
777#if XML_PARSER_DEBUG
778printf("      ident = %d\n", value);
779#endif
780        vseg[vseg_index]->ident = value;
781    } 
782    else 
783    {
784        vseg[vseg_index]->ident = 0;
785    }
786
787    /////////// get vbase attribute
788    value = getIntValue(reader, "vbase", &ok);
789    if (ok) 
790    {
791#if XML_PARSER_DEBUG
792printf("      vbase = 0x%x\n", value);
793#endif
794        vseg[vseg_index]->vbase = value;
795    }
796    else 
797    {
798        printf("[XML ERROR] illegal or missing <vbase> attribute for vseg (%d,%d)\n", 
799                vspace_index, vseg_loc_index);
800        exit(1);
801    }
802
803    ////////// get clusterid and psegname attributes
804    value = getIntValue(reader, "clusterid", &ok);
805    if (ok == 0) 
806    {
807        printf("[XML ERROR] illegal or missing <clusterid> for vseg %d\n", 
808                vseg_loc_index);
809        exit(1);
810    }
811    str = getStringValue(reader, "psegname", &ok);
812    if (ok == 0) 
813    {
814        printf("[XML ERROR] illegal or missing <psegname> for vseg %d\n", 
815                vseg_loc_index);
816        exit(1);
817    }
818
819    /////////// set psegid field
820    int index = getPsegId(value, str);
821    if (index >= 0) 
822    {
823#if XML_PARSER_DEBUG
824printf("      clusterid = %d\n", value);
825printf("      psegname  = %s\n", str);
826printf("      psegid    = %d\n", index);
827#endif
828        vseg[vseg_index]->psegid = index;
829    }
830    else 
831    {
832        printf("[XML ERROR] pseg not found for vseg %d / clusterid = %d / psegname = %s\n", 
833                vseg_loc_index, value, str );
834        exit(1);
835    } 
836
837    //////// get mode attribute
838    str = getStringValue(reader, "mode", &ok);
839#if XML_PARSER_DEBUG
840printf("      mode = %s\n", str);
841#endif
842    if      (ok && (strcmp(str, "CXWU") == 0)) { vseg[vseg_index]->mode = 0xF; }
843    else if (ok && (strcmp(str, "CXW_") == 0)) { vseg[vseg_index]->mode = 0xE; }
844    else if (ok && (strcmp(str, "CX_U") == 0)) { vseg[vseg_index]->mode = 0xD; }
845    else if (ok && (strcmp(str, "CX__") == 0)) { vseg[vseg_index]->mode = 0xC; }
846    else if (ok && (strcmp(str, "C_WU") == 0)) { vseg[vseg_index]->mode = 0xB; }
847    else if (ok && (strcmp(str, "C_W_") == 0)) { vseg[vseg_index]->mode = 0xA; }
848    else if (ok && (strcmp(str, "C__U") == 0)) { vseg[vseg_index]->mode = 0x9; }
849    else if (ok && (strcmp(str, "C___") == 0)) { vseg[vseg_index]->mode = 0x8; }
850    else if (ok && (strcmp(str, "_XWU") == 0)) { vseg[vseg_index]->mode = 0x7; }
851    else if (ok && (strcmp(str, "_XW_") == 0)) { vseg[vseg_index]->mode = 0x6; }
852    else if (ok && (strcmp(str, "_X_U") == 0)) { vseg[vseg_index]->mode = 0x5; }
853    else if (ok && (strcmp(str, "_X__") == 0)) { vseg[vseg_index]->mode = 0x4; }
854    else if (ok && (strcmp(str, "__WU") == 0)) { vseg[vseg_index]->mode = 0x3; }
855    else if (ok && (strcmp(str, "__W_") == 0)) { vseg[vseg_index]->mode = 0x2; }
856    else if (ok && (strcmp(str, "___U") == 0)) { vseg[vseg_index]->mode = 0x1; }
857    else if (ok && (strcmp(str, "____") == 0)) { vseg[vseg_index]->mode = 0x0; }
858    else {
859        printf("[XML ERROR] illegal or missing <mode> attribute for vseg (%d,%d)\n", 
860                vspace_index, vseg_loc_index);
861        exit(1);
862    }
863
864    ////////// get vobjs in vseg
865    int status = xmlTextReaderRead(reader);
866    while (status == 1) {
867        const char * tag = (const char *) xmlTextReaderConstName(reader);
868
869        if      (strcmp(tag, "vobj")     == 0 ) { vobjNode(reader); }
870        else if (strcmp(tag, "#text"  )  == 0 ) { }
871        else if (strcmp(tag, "#comment") == 0 ) { }
872        else if (strcmp(tag, "vseg")     == 0 ) 
873        {
874            vseg[vseg_index]->vobjs = vobj_count;
875            vseg_index++;
876            vseg_loc_index++;
877            return;
878        }
879        else 
880        {
881            printf("[XML ERROR] Unknown tag %s", tag);
882            exit(1);
883        }
884        status = xmlTextReaderRead (reader);
885    }
886} // end vsegNode()
887
888////////////////////////////////////////
889void vspaceNode(xmlTextReaderPtr reader) 
890{
891    char * str;
892    unsigned int ok;
893    unsigned int nb_task_vspace = 0;
894
895    vobj_loc_index = 0;
896    vseg_loc_index = 0;
897    task_loc_index = 0;
898
899    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
900
901    // checking source file consistency
902    if (vspace_index >= header->vspaces) {
903        printf("[XML ERROR] The vspace index is too large : %d\n", 
904                vspace_index);
905        exit(1);
906    }
907
908#if XML_PARSER_DEBUG
909printf("\n  vspace %d\n", vspace_index);
910#endif
911
912    vspace[vspace_index] = (mapping_vspace_t *) malloc(sizeof(mapping_vspace_t));
913
914    ////////// get name attribute
915    str = getStringValue(reader, "name", &ok);
916    if (ok) {
917#if XML_PARSER_DEBUG
918printf("  name = %s\n", str);
919#endif
920        strncpy(vspace[vspace_index]->name, str, 31);
921    }
922    else 
923    {
924        printf("[XML ERROR] illegal or missing <name> attribute for vspace %d\n", 
925                vspace_index);
926        exit(1);
927    }
928
929    ////////// set vseg_offset and task_offset attributes
930    vspace[vspace_index]->vseg_offset = vseg_index;
931    vspace[vspace_index]->vobj_offset = vobj_index;
932    vspace[vspace_index]->task_offset = task_index;
933
934#if XML_PARSER_DEBUG
935    printf("  vseg_offset = %d\n", vseg_index);
936    printf("  vobj_offset = %d\n", vobj_index);
937    printf("  task_offset = %d\n", task_index);
938#endif
939
940    ////////// get startname attribute
941    str = getStringValue(reader, "startname", &ok);
942    if (ok) {
943        //used after parsing the vobjs
944    }
945    else 
946    {
947        printf("[XML ERROR] illegal or missing <startname> attribute for vspace %s\n", 
948                vspace[vspace_index]->name);
949        exit(1);
950    }
951
952    int status = xmlTextReaderRead(reader);
953    while (status == 1) {
954        const char * tag = (const char *) xmlTextReaderConstName(reader);
955
956        if (strcmp(tag, "vseg") == 0) {
957            vsegNode(reader);
958        }
959        else if (strcmp(tag, "task") == 0) {
960            taskNode(reader);
961            nb_task_vspace++;
962        }
963        else if (strcmp(tag, "#text")    == 0) { }
964        else if (strcmp(tag, "#comment") == 0) { }
965        else if (strcmp(tag, "vspace")   == 0) {
966            vspace[vspace_index]->vobjs = vobj_loc_index; 
967            vspace[vspace_index]->tasks = task_loc_index ;
968            vspace[vspace_index]->vsegs = vseg_loc_index ;
969
970            // get index of the vobj containing the start vector
971            int index = getVobjLocId(vspace_index, str , vobj_loc_index);
972            if (index == -1) 
973            {
974                printf("[XML ERROR] vobj containing start vector not found in vspace %s\n",
975                        vspace[vspace_index]->name);
976                exit(1);
977            }
978            else 
979            {
980                vspace[vspace_index]->start_offset = index;
981#if XML_PARSER_DEBUG
982                printf("      startname = %s\n", str);
983                printf("      startid   = %d\n", index);
984                printf("  end vspace %d\n\n", vspace_index);
985#endif
986            }
987
988            // checking startid values for all tasks in vspace
989            int task_id;
990            int task_min = vspace[vspace_index]->task_offset;
991            int task_max = task_min + vspace[vspace_index]->tasks; 
992            for (task_id = task_min; task_id < task_max; task_id++) {
993                if (task[task_id]->startid >= vspace[vspace_index]->tasks) 
994                {
995                    printf("[XML ERROR] <startid> too large for task (%d,%d)\n", 
996                            vspace_index, task_id );
997                    exit(1);
998                }
999            }
1000
1001            nb_tasks_max += nb_task_vspace;
1002            vspace_index++;
1003            return;
1004        }
1005        else 
1006        {
1007            printf("[XML ERROR] Unknown tag %s", tag);
1008            exit(1);
1009        }
1010        status = xmlTextReaderRead(reader);
1011    }
1012} // end vspaceNode()
1013
1014////////////////////////////////////////
1015void cpPortNode(xmlTextReaderPtr reader) 
1016{
1017    char * str;
1018    unsigned int ok;
1019
1020    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1021
1022    if (cp_port_index >= MAX_CP_PORTS) 
1023    {
1024        printf("[XML ERROR] The number of ports (for coprocs) is larger than %d\n", 
1025                 MAX_CP_PORTS);
1026        exit(1);
1027    }
1028
1029#if XML_PARSER_DEBUG
1030    printf("\n  port %d\n", cp_port_index);
1031#endif
1032
1033    cp_port[cp_port_index] = (mapping_cp_port_t *) malloc(sizeof(mapping_cp_port_t));
1034    cp_port_vobj_ref[cp_port_index] = (vobj_ref_t *) malloc(sizeof(vobj_ref_t));
1035
1036    ///////// get direction attribute
1037    str = getStringValue(reader, "direction", &ok);
1038    if (ok) 
1039    {
1040#if XML_PARSER_DEBUG
1041        printf("      direction = %s\n", str);
1042#endif
1043        if (strcmp(str, "TO_COPROC")   ==  0) 
1044        {
1045            cp_port[cp_port_index]->direction = PORT_TO_COPROC;
1046        }
1047        else if (strcmp(str, "FROM_COPROC") ==  0) 
1048        {
1049            cp_port[cp_port_index]->direction = PORT_FROM_COPROC;
1050        }
1051        else 
1052        {
1053            printf("[XML ERROR] illegal <direction> for cp_port %d in cluster %d\n",
1054                    cp_port_index, cluster_index);
1055            exit(1);
1056        }
1057    } 
1058    else 
1059    {
1060        printf("[XML ERROR] missing <direction> for cp_port %d in cluster %d\n",
1061                cp_port_index, cluster_index);
1062        exit(1);
1063    }
1064
1065    /////////// get vspacename attribute
1066    str = getStringValue(reader, "vspacename", &ok);
1067#if XML_PARSER_DEBUG
1068    printf("      vspacename = %s\n", str);
1069#endif
1070    if (ok) 
1071    {
1072        strncpy(cp_port_vobj_ref[cp_port_index]->vspace_name, str, 31);
1073    }
1074    else 
1075    {
1076        printf("[XML ERROR] missing <vspacename> for cp_port %d in cluster %d\n",
1077                cp_port_index, cluster_index);
1078        exit(1);
1079    }
1080
1081    /////////// get vobjname attribute
1082    str = getStringValue(reader, "vobjname", &ok);
1083#if XML_PARSER_DEBUG
1084    printf("      vobjname = %s\n", str);
1085#endif
1086    if (ok) 
1087    {
1088        strncpy(cp_port_vobj_ref[cp_port_index]->vobj_name, str, 31);
1089    }
1090    else 
1091    {
1092        printf("[XML ERROR] missing <vobjname> for cp_port %d in cluster %d\n",
1093                cp_port_index, cluster_index);
1094        exit(1);
1095    }
1096    cp_port_index++;
1097    cp_port_loc_index++;
1098} // end cpPortNode()
1099
1100////////////////////////////////////////
1101void periphNode(xmlTextReaderPtr reader) 
1102{
1103    char * str;
1104    unsigned int value;
1105    unsigned int ok;
1106
1107    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1108
1109    if (periph_index >= MAX_PERIPHS) 
1110    {
1111        printf("[XML ERROR] The number of periphs is larger than %d\n", MAX_PERIPHS);
1112        exit(1);
1113    }
1114
1115#if XML_PARSER_DEBUG
1116    printf("\n  periph %d\n", periph_index);
1117#endif
1118
1119    periph[periph_index] = (mapping_periph_t *) malloc(sizeof(mapping_periph_t));
1120
1121    ///////// get channels attribute (optionnal : 1 if missing)
1122    value = getIntValue(reader, "channels", &ok);
1123    if (ok) 
1124    {
1125#if XML_PARSER_DEBUG
1126        printf("      channels = %d\n", value);
1127#endif
1128        periph[periph_index]->channels = value;
1129    }
1130    else 
1131    {
1132        periph[periph_index]->channels = 1;
1133    }
1134
1135    /////////// get psegname attribute
1136    str = getStringValue(reader, "psegname", &ok);
1137    if (ok == 0) 
1138    {
1139        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 
1140                coproc_index, cluster_index);
1141        exit(1);
1142    }
1143
1144    /////////// set psegid attribute
1145    int index = getPsegId(cluster_index, str);
1146    if (index >= 0) 
1147    {
1148#if XML_PARSER_DEBUG
1149        printf("      clusterid = %d\n", cluster_index);
1150        printf("      psegname  = %s\n", str);
1151        printf("      psegid    = %d\n", index);
1152#endif
1153        periph[periph_index]->psegid = index;
1154        assert(pseg[index]->type == PSEG_TYPE_PERI && 
1155                "peripheral psegname attribute must refer to a pseg of type PERI" );
1156    }
1157    else 
1158    {
1159        printf("[XML ERROR] pseg not found for periph %d / clusterid = %d / psegname = %s\n", 
1160                periph_loc_index, cluster_index, str );
1161        exit(1);
1162    } 
1163
1164    /////////// get type attribute
1165    str = getStringValue(reader, "type", &ok);
1166    if (ok) 
1167    {
1168#if XML_PARSER_DEBUG
1169        printf("      type     = %s\n", str);
1170#endif
1171        unsigned int error = 0;
1172
1173        // The TTY, IOC, NIC, FBF, CMA and IOB peripherals are not replicated in all clusters
1174        // but can be replicated in two different clusters for fault tolerance
1175        // In case of replication, the number of channels must be the same
1176        if (strcmp(str, "IOC") == 0) 
1177        {
1178            periph[periph_index]->type = PERIPH_TYPE_IOC;
1179            if (header->ioc_cluster == 0xFFFFFFFF)
1180            {
1181                header->ioc_cluster  = cluster_index; 
1182                ioc_channels = periph[periph_index]->channels;
1183            }
1184            else if (header->ioc_cluster_bis == 0xFFFFFFFF) 
1185            {
1186                header->ioc_cluster_bis = cluster_index;
1187            }
1188            else
1189            {
1190                error = 1;
1191            }
1192        } 
1193        else if (strcmp(str, "TTY") == 0) 
1194        {
1195            periph[periph_index]->type = PERIPH_TYPE_TTY;
1196            if (header->tty_cluster == 0xFFFFFFFF) 
1197            {
1198                header->tty_cluster = cluster_index;
1199                tty_channels = periph[periph_index]->channels;
1200            }
1201            else if (header->tty_cluster_bis == 0xFFFFFFFF) 
1202            {
1203                header->tty_cluster_bis = cluster_index;
1204            }
1205            else 
1206            {
1207                error = 1;
1208            }
1209        }
1210        else if (strcmp(str, "FBF") == 0) 
1211        {
1212            periph[periph_index]->type = PERIPH_TYPE_FBF;
1213            if (header->fbf_cluster == 0xFFFFFFFF) 
1214            {
1215                header->fbf_cluster = cluster_index; 
1216            }
1217            else if (header->fbf_cluster_bis == 0xFFFFFFFF) 
1218            {
1219                header->fbf_cluster_bis = cluster_index; 
1220            }
1221            else 
1222            {
1223                error = 1;
1224            }
1225        }
1226        else if (strcmp(str, "NIC") == 0) 
1227        {
1228            periph[periph_index]->type = PERIPH_TYPE_NIC;
1229            if (header->nic_cluster == 0xFFFFFFFF) 
1230            {
1231                header->nic_cluster = cluster_index;
1232                nic_channels = periph[periph_index]->channels;
1233            }
1234            else if (header->nic_cluster_bis == 0xFFFFFFFF) 
1235            {
1236                header->nic_cluster_bis = cluster_index;
1237            }
1238            else 
1239            {
1240                error = 1;
1241            }
1242        }
1243        else if (strcmp(str, "CMA") == 0) 
1244        {
1245            periph[periph_index]->type = PERIPH_TYPE_CMA;
1246            if (header->cma_cluster == 0xFFFFFFFF) 
1247            {
1248                header->cma_cluster = cluster_index;
1249                cma_channels = periph[periph_index]->channels;
1250            }
1251            else if (header->cma_cluster_bis == 0xFFFFFFFF) 
1252            {
1253                header->cma_cluster_bis = cluster_index;
1254            }
1255            else 
1256            {
1257                error = 1;
1258            }
1259        }
1260        else if (strcmp(str, "IOB") == 0) 
1261        {
1262            periph[periph_index]->type = PERIPH_TYPE_IOB;
1263            use_iob = 1;
1264            if (header->iob_cluster == 0xFFFFFFFF) 
1265            {
1266                header->iob_cluster = cluster_index; 
1267            }
1268            else if (header->iob_cluster_bis == 0xFFFFFFFF) 
1269            {
1270                header->iob_cluster_bis = cluster_index; 
1271            }
1272            else 
1273            {
1274                error = 1;
1275            }
1276        }
1277        else if (strcmp(str, "SIM") == 0) 
1278        {
1279            periph[periph_index]->type = PERIPH_TYPE_SIM;
1280            if (header->sim_cluster == 0xFFFFFFFF) 
1281            {
1282                header->sim_cluster = cluster_index; 
1283            }
1284            else if (header->sim_cluster_bis == 0xFFFFFFFF) 
1285            {
1286                header->sim_cluster_bis = cluster_index; 
1287            }
1288            else
1289            {
1290                error = 1;
1291            }
1292        }
1293        // The TIM, ICU, XICU, DMA, MEMC peripherals are replicated in all clusters
1294        // but it must exist only one component of each type per cluster
1295        else if (strcmp(str, "TIM") == 0 ) 
1296        {
1297            periph[periph_index]->type = PERIPH_TYPE_TIM;
1298            if (found_timer || use_xcu)  error = 1; 
1299            found_timer = 1;
1300            if (tim_channels < periph[periph_index]->channels) 
1301            {
1302                tim_channels = periph[periph_index]->channels;
1303            }
1304        }
1305        else if (strcmp(str, "ICU") == 0) 
1306        {
1307            periph[periph_index]->type = PERIPH_TYPE_ICU;
1308            if (found_icu || use_xcu)  error = 1; 
1309            found_icu = 1;
1310        }
1311        else if (strcmp(str, "XCU") == 0) 
1312        {
1313            periph[periph_index]->type = PERIPH_TYPE_XCU;
1314            if (found_icu || found_timer)  error = 1; 
1315            found_xcu    = 1;
1316            found_timer  = 1;
1317            tim_channels = 32; 
1318            use_xcu      = 1;
1319        }
1320        else if (strcmp(str, "DMA") == 0) 
1321        {
1322            periph[periph_index]->type = PERIPH_TYPE_DMA;
1323            if (found_dma)  error = 1; 
1324            found_dma = 1;
1325            if (dma_channels < periph[periph_index]->channels)
1326                dma_channels = periph[periph_index]->channels;
1327        }
1328        else if (strcmp(str, "MMC") == 0) 
1329        {
1330            periph[periph_index]->type = PERIPH_TYPE_MMC;
1331            if (found_mmc)  error = 1; 
1332            found_mmc = 1;
1333            if ( periph[periph_index]->channels != 1 ) error = 1;
1334        }
1335        else 
1336        {
1337            printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n",
1338                    periph_loc_index, cluster_index);
1339            exit(1);
1340        }
1341
1342        if (error) 
1343        {
1344            printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n",
1345                    periph_loc_index, cluster_index);
1346            exit(1);
1347        }
1348    }
1349    else 
1350    {
1351        printf("[XML ERROR] missing <type> for peripheral  %d in cluster %d\n",
1352                periph_loc_index, cluster_index);
1353        exit(1);
1354    }
1355
1356    periph_index++;
1357    periph_loc_index++;
1358    cluster[cluster_index]->periphs++;
1359
1360} // end periphNode
1361
1362////////////////////////////////////////
1363void coprocNode(xmlTextReaderPtr reader) 
1364{
1365    char * str;
1366    unsigned int ok;
1367
1368    cp_port_loc_index = 0;
1369
1370    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1371
1372    if (coproc_index >= MAX_COPROCS) 
1373    {
1374        printf("[XML ERROR] The number of coprocs is larger than %d\n", MAX_COPROCS);
1375        exit(1);
1376    }
1377
1378#if XML_PARSER_DEBUG
1379    printf("\n  coproc %d\n", coproc_index);
1380#endif
1381
1382    coproc[coproc_index] = (mapping_coproc_t *) malloc(sizeof(mapping_coproc_t));
1383
1384    /////////// get name attribute
1385    str = getStringValue(reader, "name", &ok);
1386    if (ok) 
1387    {
1388#if XML_PARSER_DEBUG
1389        printf("      name = %s\n", str);
1390#endif
1391        strncpy(coproc[coproc_index]->name, str, 31);
1392    }
1393    else 
1394    {
1395        printf("[XML ERROR] illegal or missing <name> for coproc %d in cluster %d\n",
1396                coproc_index, cluster_index);
1397        exit(1);
1398    }
1399
1400    /////////// get psegname attribute
1401    str = getStringValue(reader, "psegname", &ok);
1402    if (ok == 0) 
1403    {
1404        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 
1405                coproc_index, cluster_index);
1406        exit(1);
1407    }
1408
1409    /////////// set psegid attribute
1410    int index = getPsegId(cluster_index, str);
1411    if (index >= 0) 
1412    {
1413#if XML_PARSER_DEBUG
1414        printf("      clusterid = %d\n", cluster_index);
1415        printf("      psegname  = %s\n", str);
1416        printf("      psegid    = %d\n", index);
1417#endif
1418        coproc[coproc_index]->psegid = index;
1419        assert(pseg[index]->type == PSEG_TYPE_PERI && "coproc psegname attribute must refer to a pseg of type PERI" );
1420    }
1421    else 
1422    {
1423        printf("[XML ERROR] pseg not found for coproc %d / clusterid = %d / psegname = %s\n", 
1424                coproc_index, cluster_index, str );
1425        exit(1);
1426    } 
1427
1428    ////////// set port_offset
1429    coproc[coproc_index]->port_offset = cp_port_index;
1430
1431#if XML_PARSER_DEBUG
1432    printf("      port_offset = %d\n", cp_port_index);
1433#endif
1434
1435    int status = xmlTextReaderRead(reader);
1436    while (status == 1) 
1437    {
1438        const char * tag = (const char *) xmlTextReaderConstName(reader);
1439
1440        if (strcmp(tag, "port") == 0 ) 
1441        {
1442            cpPortNode(reader);
1443        }
1444        else if (strcmp(tag, "#text")    == 0 ) { }
1445        else if (strcmp(tag, "#comment") == 0 ) { }
1446        else if (strcmp(tag, "coproc") == 0 ) 
1447        {
1448            coproc[coproc_index]->ports = cp_port_loc_index;
1449            cluster[cluster_index]->coprocs++;
1450            coproc_loc_index++;
1451            coproc_index++;
1452            return;
1453        }
1454        else 
1455        {
1456            printf("[XML ERROR] Unknown tag %s", tag);
1457            exit(1);
1458        }
1459        status = xmlTextReaderRead(reader);
1460    }
1461} // end coprocNode()
1462
1463
1464/////////////////////////////////////
1465void irqNode(xmlTextReaderPtr reader) 
1466{
1467    unsigned int ok;
1468    unsigned int value;
1469    char * str;
1470
1471    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1472
1473    if (irq_index >= MAX_IRQS) {
1474        printf("[XML ERROR] The number of irqs is larger than %d\n", MAX_IRQS);
1475    }
1476
1477#if XML_PARSER_DEBUG
1478    printf("     irq %d\n", irq_loc_index);
1479#endif
1480
1481    irq[irq_index] = (mapping_irq_t *) malloc(sizeof(mapping_irq_t));
1482
1483    ///////// get type attribute
1484    str = getStringValue(reader, "type", &ok);
1485    if (ok) 
1486    {
1487#if XML_PARSER_DEBUG
1488        printf("        type    = %s\n", str);
1489#endif
1490        if (strcmp(str, "HARD") == 0 ) irq[irq_index]->type = 0;
1491        else                           irq[irq_index]->type = 1;
1492    }
1493    else 
1494    {
1495        printf("[XML ERROR] missing IRQ <type> for processor %d in cluster %d\n",
1496                cluster_index, proc_loc_index);
1497        exit(1);
1498    }
1499
1500    ///////// get icuid attribute
1501    value = getIntValue(reader, "icuid", &ok);
1502    if (ok) 
1503    {
1504#if XML_PARSER_DEBUG
1505        printf("        icuid   = %d\n", value);
1506#endif
1507        irq[irq_index]->icuid = value;
1508        if (value >= 32) 
1509        {
1510            printf("[XML ERROR] IRQ <icuid> too large for processor %d in cluster %d\n",
1511                    cluster_index, proc_loc_index);
1512            exit(1);
1513        }
1514    }
1515    else 
1516    {
1517        printf("[XML ERROR] missing IRQ <icuid> for processor %d in cluster %d\n",
1518                cluster_index, proc_loc_index);
1519        exit(1);
1520    }
1521
1522    ///////// get isr attribute
1523    str = getStringValue(reader, "isr", &ok);
1524    if (ok) 
1525    {
1526#if XML_PARSER_DEBUG
1527        printf("        isr     = %s\n", str);
1528#endif
1529        if      (strcmp(str, "ISR_SWITCH" ) == 0) { irq[irq_index]->isr = ISR_SWITCH; }
1530        else if (strcmp(str, "ISR_IOC"    ) == 0) { irq[irq_index]->isr = ISR_IOC; }
1531        else if (strcmp(str, "ISR_DMA"    ) == 0) { irq[irq_index]->isr = ISR_DMA; }
1532        else if (strcmp(str, "ISR_TTY"    ) == 0) { irq[irq_index]->isr = ISR_TTY; }
1533        else if (strcmp(str, "ISR_TIMER"  ) == 0) { irq[irq_index]->isr = ISR_TIMER; }
1534        else 
1535        {
1536            printf("[XML ERROR] illegal IRQ <isr> for processor %d in cluster %d\n",
1537                    cluster_index, proc_loc_index);
1538            exit(1);
1539        }
1540#if XML_PARSER_DEBUG
1541        printf("        isrnum  = %d\n", irq[irq_index]->isr);
1542#endif
1543    } 
1544    else 
1545    {
1546        printf("[XML ERROR] missing IRQ <isr> for processor %d in cluster %d\n",
1547                cluster_index, proc_loc_index);
1548        exit(1);
1549    }
1550
1551    ///////// get channel attribute (optionnal : 0 if missing)
1552    value = getIntValue(reader, "channel", &ok);
1553    if (ok) 
1554    {
1555#if XML_PARSER_DEBUG
1556        printf("        channel = %d\n", value);
1557#endif
1558        irq[irq_index]->channel = value;
1559    }
1560    else 
1561    {
1562        irq[irq_index]->channel = 0;
1563    }
1564
1565    irq_index++;
1566    irq_loc_index++;
1567
1568} // end irqNode
1569
1570
1571//////////////////////////////////////
1572void procNode(xmlTextReaderPtr reader) 
1573{
1574    unsigned int ok;
1575    unsigned int value;
1576
1577    irq_loc_index = 0;
1578
1579    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1580
1581    if (proc_index >= MAX_PROCS) 
1582    {
1583        printf("[XML ERROR] The number of procs is larger than %d\n", MAX_PROCS);
1584        exit(1);
1585    }
1586
1587#if XML_PARSER_DEBUG
1588    printf("\n  proc %d\n", proc_index);
1589#endif
1590
1591    proc[proc_index] = (mapping_proc_t *) malloc(sizeof(mapping_proc_t));
1592
1593    /////////// get index attribute (optional)
1594    value = getIntValue(reader, "index", &ok);
1595    if (ok && (value != proc_loc_index)) 
1596    {
1597        printf("[XML ERROR] wrong proc index / expected value is %d", 
1598                proc_loc_index);
1599        exit(1);
1600    }
1601
1602    ////////// set irq_offset attribute
1603    proc[proc_index]->irq_offset = irq_index;
1604
1605#if XML_PARSER_DEBUG
1606    printf("    irq_offset = %d\n", irq_index);
1607#endif
1608
1609    int status = xmlTextReaderRead(reader);
1610    while (status == 1) 
1611    {
1612        const char * tag = (const char *) xmlTextReaderConstName(reader);
1613
1614        if (strcmp(tag, "irq") == 0) 
1615        {
1616            irqNode(reader);
1617        }
1618        else if (strcmp(tag, "#text")    == 0) { }
1619        else if (strcmp(tag, "#comment") == 0) { }
1620        else if (strcmp(tag, "proc")     == 0) 
1621        {
1622            proc[proc_index]->irqs = irq_loc_index;
1623            cluster[cluster_index]->procs++;
1624            proc_loc_index++;
1625            proc_index++;
1626            return;
1627        }
1628        else 
1629        {
1630            printf("[XML ERROR] Unknown tag %s", tag);
1631            exit(1);
1632        }
1633        status = xmlTextReaderRead(reader);
1634    }
1635} // end procNode()
1636
1637
1638//////////////////////////////////////
1639void psegNode(xmlTextReaderPtr reader) 
1640{
1641    unsigned int ok;
1642    paddr_t      ll_value;
1643    char * str;
1644
1645    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1646
1647    if (pseg_index >= MAX_PSEGS) 
1648    {
1649        printf("[XML ERROR] The number of psegs is larger than %d\n", MAX_PSEGS);
1650        exit(1);
1651    }
1652
1653#if XML_PARSER_DEBUG
1654    printf("    pseg %d\n", pseg_index);
1655#endif
1656
1657    pseg[pseg_index] = (mapping_pseg_t *) malloc(sizeof(mapping_pseg_t));
1658
1659    /////// get name attribute
1660    str = getStringValue(reader, "name", &ok);
1661#if XML_PARSER_DEBUG
1662    printf("      name = %s\n", str);
1663#endif
1664    if (ok) 
1665    {
1666        strncpy(pseg[pseg_index]->name, str, 31);
1667    }
1668    else 
1669    {
1670        printf("[XML ERROR] illegal or missing <name> for pseg %d in cluster %d\n",
1671                pseg_index, cluster_index);
1672        exit(1);
1673    }
1674
1675    //////// get type attribute
1676    str = getStringValue(reader, "type", &ok);
1677#if XML_PARSER_DEBUG
1678    printf("      type = %s\n", str);
1679#endif
1680    if      (ok && (strcmp(str, "RAM" ) == 0)) { pseg[pseg_index]->type = PSEG_TYPE_RAM; }
1681    else if (ok && (strcmp(str, "ROM" ) == 0)) { pseg[pseg_index]->type = PSEG_TYPE_ROM; }
1682    else if (ok && (strcmp(str, "PERI") == 0)) { pseg[pseg_index]->type = PSEG_TYPE_PERI; }
1683    else 
1684    {
1685        printf("[XML ERROR] illegal or missing <type> for pseg %s in cluster %d\n",
1686                pseg[pseg_index]->name, cluster_index);
1687        exit(1);
1688    }
1689
1690    //////// get base attribute
1691    ll_value = getPaddrValue(reader, "base", &ok);
1692#if XML_PARSER_DEBUG
1693    printf("      base = 0x%llx\n", ll_value);
1694#endif
1695    if (ok) 
1696    {
1697        pseg[pseg_index]->base = ll_value;
1698    }
1699    else {
1700        printf("[XML ERROR] illegal or missing <base> for pseg %s in cluster %d\n",
1701                pseg[pseg_index]->name, cluster_index);
1702        exit(1);
1703    }
1704
1705    //////// get length attribute
1706    ll_value = getPaddrValue(reader, "length", &ok);
1707#if XML_PARSER_DEBUG
1708    printf("      length = 0x%llx\n", ll_value);
1709#endif
1710    if (ok) 
1711    {
1712        pseg[pseg_index]->length = ll_value;
1713    } 
1714    else 
1715    {
1716        printf("[XML ERROR] illegal or missing <length> for pseg %s in cluster %d\n",
1717                pseg[pseg_index]->name, cluster_index);
1718        exit(1);
1719    }
1720
1721    //////// set cluster attribute
1722    pseg[pseg_index]->cluster = cluster_index;
1723
1724    pseg_index++;
1725    cluster[cluster_index]->psegs++;
1726} // end psegNode()
1727
1728
1729/////////////////////////////////////////
1730void clusterNode(xmlTextReaderPtr reader) 
1731{
1732    unsigned int ok;
1733    unsigned int value;
1734
1735    cluster[cluster_index] = (mapping_cluster_t *) malloc(sizeof(mapping_cluster_t));
1736
1737    //initialise all variables
1738    //they will be incremented by *Node() functions
1739    //FIXME: calloc?
1740    cluster[cluster_index]->psegs = 0;
1741    cluster[cluster_index]->procs = 0;
1742    cluster[cluster_index]->coprocs = 0;
1743    cluster[cluster_index]->periphs = 0;
1744
1745
1746    //initialise global variables
1747    //TODO: delete those three
1748    proc_loc_index = 0;
1749    coproc_loc_index = 0;
1750    periph_loc_index = 0;
1751
1752    // for replicated periph
1753    found_timer = 0;
1754    found_icu   = 0;
1755    found_xcu   = 0;
1756    found_dma   = 0;
1757    found_mmc   = 0;
1758
1759    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
1760        return;
1761    }
1762
1763    // checking source file consistency
1764    if (cluster_index >= header->clusters) 
1765    {
1766        printf("[XML ERROR] The cluster index is too large : %d\n", cluster_index);
1767        exit(1);
1768    }
1769
1770#if XML_PARSER_DEBUG
1771    printf("  cluster %d\n", cluster_index);
1772#endif
1773
1774
1775    /////////// check cluster index attribute (optional)
1776    value = getIntValue(reader, "index", &ok);
1777    if (ok && (value != cluster_index)) 
1778    {
1779        printf("[XML ERROR] wrong cluster index / expected value is %d", 
1780                cluster_index);
1781        exit(1);
1782    }
1783
1784    ////////// set offsets
1785    cluster[cluster_index]->pseg_offset = pseg_index;
1786    cluster[cluster_index]->proc_offset = proc_index;
1787    cluster[cluster_index]->coproc_offset = coproc_index;
1788    cluster[cluster_index]->periph_offset = periph_index;
1789
1790#if XML_PARSER_DEBUG
1791    printf("    pseg_offset   = %d\n", pseg_index);
1792    printf("    proc_offset   = %d\n", proc_index);
1793    printf("    coproc_offset = %d\n", coproc_index);
1794    printf("    periph_offset = %d\n", coproc_index);
1795#endif
1796
1797    ////////// get psegs, procs, coprocs and periphs
1798    int status = xmlTextReaderRead(reader);
1799
1800    while (status == 1) 
1801    {
1802        const char * tag = (const char *) xmlTextReaderConstName(reader);
1803
1804        if      (strcmp(tag, "pseg")     == 0) psegNode(reader);
1805        else if (strcmp(tag, "proc")     == 0) procNode(reader);
1806        else if (strcmp(tag, "coproc")   == 0) coprocNode(reader);
1807        else if (strcmp(tag, "periph")   == 0) periphNode(reader);
1808        else if (strcmp(tag, "#text")    == 0) { }
1809        else if (strcmp(tag, "#comment") == 0) { }
1810        else if (strcmp(tag, "cluster")  == 0) 
1811        {
1812
1813            ///////// TIMER and ICU peripheral are mandatory //////////////
1814            if (!found_timer && !found_xcu)
1815            {
1816                printf("[XML ERROR] missing timer peripheral in cluster %d\n", cluster_index);
1817                exit(1);
1818            }
1819
1820            if (!found_icu && !found_xcu) 
1821            {
1822                printf("[XML ERROR] missing icu peripheral in cluster %d\n", cluster_index);
1823                exit(1);
1824            }
1825
1826            if (nb_proc_max < cluster[cluster_index]->procs) 
1827            {
1828                nb_proc_max = cluster[cluster_index]->procs;
1829            }
1830
1831#if XML_PARSER_DEBUG
1832            printf("    psegs   = %d\n", cluster[cluster_index]->psegs);
1833            printf("    procs   = %d\n", cluster[cluster_index]->procs);
1834            printf("    coprocs = %d\n", cluster[cluster_index]->coprocs);
1835            printf("    periphs = %d\n", cluster[cluster_index]->periphs);
1836            printf("    end cluster %d\n", cluster_index);
1837#endif
1838            cluster_index++;
1839            return;
1840        }
1841        status = xmlTextReaderRead(reader);
1842    }
1843} // end clusterNode()
1844
1845
1846//////////////////////////////////////////////
1847void clusterSetNode(xmlTextReaderPtr reader) 
1848{
1849    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1850
1851#if XML_PARSER_DEBUG
1852    printf("\n  clusters set\n");
1853#endif
1854
1855    int status = xmlTextReaderRead(reader);
1856    while (status == 1) 
1857    {
1858        const char * tag = (const char *) xmlTextReaderConstName(reader);
1859
1860        if      (strcmp(tag, "cluster")    == 0) { clusterNode(reader); }
1861        else if (strcmp(tag, "#text")      == 0) { }
1862        else if (strcmp(tag, "#comment")   == 0) { }
1863        else if (strcmp(tag, "clusterset") == 0) 
1864        {
1865            // checking source file consistency
1866            if (cluster_index != header->clusters) 
1867            {
1868                printf("[XML ERROR] Wrong number of clusters\n");
1869                exit(1);
1870            }
1871
1872            // At least one TTY terminal for system boot
1873            if (header->tty_cluster == 0xFFFFFFFF) 
1874            {
1875                printf("[XML ERROR] illegal or missing tty peripheral");
1876                exit(1);
1877            }
1878
1879#if XML_PARSER_DEBUG
1880            printf("  end cluster set\n\n");
1881#endif
1882            header->psegs = pseg_index;
1883            header->procs = proc_index;
1884            header->irqs = irq_index;
1885            header->coprocs = coproc_index;
1886            header->cp_ports = cp_port_index;
1887            header->periphs = periph_index;
1888            return;
1889        }
1890        else 
1891        {
1892            printf("[XML ERROR] Unknown tag in clusterset node : %s",tag);
1893            exit(1);
1894        }
1895        status = xmlTextReaderRead(reader);
1896    }
1897} // end clusterSetNode()
1898
1899
1900///////////////////////////////////////////
1901void globalSetNode(xmlTextReaderPtr reader) 
1902{
1903    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1904
1905#if XML_PARSER_DEBUG
1906    printf("  globals set\n");
1907#endif
1908
1909    int status = xmlTextReaderRead(reader);
1910    while (status == 1) 
1911    {
1912        const char * tag = (const char *) xmlTextReaderConstName(reader);
1913
1914        if      (strcmp(tag, "vseg")      == 0) { vsegNode(reader); }
1915        else if (strcmp(tag, "#text")     == 0) { }
1916        else if (strcmp(tag, "#comment")  == 0) { }
1917        else if (strcmp(tag, "globalset") == 0) 
1918        {
1919#if XML_PARSER_DEBUG
1920            printf("  end global set\n\n");
1921#endif
1922            header->globals = vseg_index;
1923            vseg_loc_index = 0;
1924            return;
1925        }
1926        else 
1927        {
1928            printf("[XML ERROR] Unknown tag in globalset node : %s",tag);
1929            exit(1);
1930        }
1931        status = xmlTextReaderRead(reader);
1932    }
1933} // end globalSetNode()
1934
1935
1936///////////////////////////////////////////
1937void vspaceSetNode(xmlTextReaderPtr reader)
1938{
1939    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
1940        return;
1941    }
1942
1943#if XML_PARSER_DEBUG
1944    printf("\n  vspaces set\n");
1945#endif
1946
1947    int status = xmlTextReaderRead ( reader );
1948    while (status == 1) {
1949        const char * tag = (const char *) xmlTextReaderConstName(reader);
1950
1951        if (strcmp(tag, "vspace") == 0) {
1952            vspaceNode(reader);
1953        }
1954        else if (strcmp(tag, "#text"    ) == 0 ) { }
1955        else if (strcmp(tag, "#comment" ) == 0 ) { }
1956        else if (strcmp(tag, "vspaceset") == 0 ) 
1957        {
1958            // checking source file consistency
1959            if (vspace_index != header->vspaces) 
1960            {
1961                printf("[XML ERROR] Wrong number of vspaces\n");
1962                exit(1);
1963            }
1964            else 
1965            {
1966                header->vsegs = vseg_index;
1967                header->vobjs = vobj_index;
1968                header->tasks = task_index;
1969                return;
1970            }
1971        }
1972        else 
1973        {
1974            printf("[XML ERROR] Unknown tag in vspaceset node : %s",tag);
1975            exit(1);
1976        }
1977        status = xmlTextReaderRead(reader);
1978    }
1979} // end globalSetNode()
1980
1981
1982////////////////////////////////////////
1983void headerNode(xmlTextReaderPtr reader) 
1984{
1985    char * name;
1986    unsigned int value;
1987    unsigned int ok;
1988
1989    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
1990
1991#if XML_PARSER_DEBUG
1992    printf("mapping_info\n");
1993#endif
1994
1995    header = (mapping_header_t *) malloc(sizeof(mapping_header_t));
1996
1997    ////////// get name attribute
1998    name = getStringValue(reader, "name", &ok);
1999    if (ok) 
2000    {
2001#if XML_PARSER_DEBUG
2002        printf("  name = %s\n", name);
2003#endif
2004        strncpy( header->name, name, 31);
2005    }
2006    else 
2007    {
2008        printf("[XML ERROR] illegal or missing <name> attribute in header\n");
2009        exit(1);
2010    }
2011
2012    /////////// get cluster_x attribute
2013    cluster_x = getIntValue(reader, "cluster_x", &ok);
2014    if (ok) 
2015    {
2016#if XML_PARSER_DEBUG
2017        printf("  cluster_x = %d\n", cluster_x);
2018#endif
2019        header->cluster_x = cluster_x;
2020    }
2021    else 
2022    {
2023        printf("[XML ERROR] illegal or missing <cluster_x> attribute in header\n");
2024        exit(1);
2025    }
2026
2027    /////////// get cluster_y attribute
2028    cluster_y = getIntValue(reader, "cluster_y", &ok);
2029    if (ok) 
2030    {
2031#if XML_PARSER_DEBUG
2032        printf("  cluster_y = %d\n", cluster_y);
2033#endif
2034        header->cluster_y = cluster_y;
2035    }
2036    else 
2037    {
2038        printf("[XML ERROR] illegal or missing <cluster_y> attribute in header\n");
2039        exit(1);
2040    }
2041
2042    //check the number of cluster
2043    value = cluster_x * cluster_y;
2044    if (value >= MAX_CLUSTERS) 
2045    {
2046        printf("[XML ERROR] The number of clusters is larger than %d\n", MAX_CLUSTERS);
2047        exit(1);
2048    }
2049
2050    header->clusters  = value;
2051
2052#if XML_PARSER_DEBUG
2053    printf("  clusters = %d\n", value);
2054#endif
2055
2056    ///////// get vspaces attribute
2057    value = getIntValue(reader, "vspaces", &ok);
2058    if (ok) 
2059    {
2060        if (value >= MAX_VSPACES) 
2061        {
2062            printf("[XML ERROR] The number of vspaces is larger than %d\n", MAX_VSPACES);
2063            exit(1);
2064        }
2065#if XML_PARSER_DEBUG
2066        printf("  vspaces = %d\n", value);
2067#endif
2068        header->vspaces  = value;
2069    }
2070    else 
2071    {
2072        printf("[XML ERROR] illegal or missing <vspaces> attribute in mapping\n");
2073        exit(1);
2074    }
2075
2076    ///////// get increment attribute
2077    value = getIntValue(reader, "increment", &ok);
2078    if (ok) 
2079    {
2080        if ( (value != 0x10000) && (value != 0x8000) &&
2081             (value != 0x4000)  && (value != 0x2000) )
2082       
2083        {
2084            printf("[XML ERROR] The vseg increment must be one of the following: ");
2085            printf(" 0x00010000 / 0x00008000 / 0x00004000 / 0x00002000");
2086            exit(1);
2087        }
2088#if XML_PARSER_DEBUG
2089        printf("  increment = %d\n", value);
2090#endif
2091        header->increment  = value;
2092    }
2093    else 
2094    {
2095        printf("[XML ERROR] illegal or missing <increment> attribute in mapping\n");
2096        exit(1);
2097    }
2098
2099    //////// initialise non replicated peripherals cluster index
2100    header->tty_cluster = 0xFFFFFFFF;
2101    header->nic_cluster = 0xFFFFFFFF;
2102    header->ioc_cluster = 0xFFFFFFFF;
2103    header->fbf_cluster = 0xFFFFFFFF;
2104    header->cma_cluster = 0xFFFFFFFF;
2105    header->iob_cluster = 0xFFFFFFFF;
2106    header->sim_cluster = 0xFFFFFFFF;
2107    header->tty_cluster_bis = 0xFFFFFFFF;
2108    header->nic_cluster_bis = 0xFFFFFFFF;
2109    header->ioc_cluster_bis = 0xFFFFFFFF;
2110    header->fbf_cluster_bis = 0xFFFFFFFF;
2111    header->cma_cluster_bis = 0xFFFFFFFF;
2112    header->iob_cluster_bis = 0xFFFFFFFF;
2113    header->sim_cluster_bis = 0xFFFFFFFF;
2114
2115    ///////// set signature
2116    header->signature = IN_MAPPING_SIGNATURE;
2117
2118    int status = xmlTextReaderRead(reader);
2119    while (status == 1) 
2120    {
2121        const char * tag = (const char *) xmlTextReaderConstName(reader);
2122
2123        if (strcmp(tag, "clusterset") == 0) 
2124        {
2125            clusterSetNode(reader);
2126        }
2127        else if (strcmp(tag, "globalset")    == 0) { globalSetNode(reader); }
2128        else if (strcmp(tag, "vspaceset")    == 0) { vspaceSetNode(reader); }
2129        else if (strcmp(tag, "#text")        == 0) { }
2130        else if (strcmp(tag, "#comment")     == 0) { }
2131        else if (strcmp(tag, "mapping_info") == 0) 
2132        {
2133#if XML_PARSER_DEBUG
2134            printf("end mapping_info\n");
2135#endif
2136            return;
2137        }
2138        else 
2139        {
2140            printf("[XML ERROR] Unknown tag in header node : %s\n",tag);
2141            exit(1);
2142        }
2143        status = xmlTextReaderRead(reader);
2144    }
2145} // end headerNode()
2146
2147
2148///////////////////////////////////////
2149void BuildTable(int fdout, const char * type, unsigned int nb_elem,
2150                unsigned int elem_size, char ** table) 
2151{
2152    unsigned int i;
2153    // write element
2154    for (i = 0; i < nb_elem; i++) {
2155        if (elem_size != write(fdout, table[i], elem_size)) {
2156            printf("function %s: %s(%d) write  error \n", __FUNCTION__, type, i);
2157            exit(1);
2158        }
2159
2160#if XML_PARSER_DEBUG
2161        printf("Building binary: writing %s %d\n", type, i);
2162#endif
2163    }
2164}
2165
2166/////////////////////////////////////
2167int open_file(const char * file_path) 
2168{
2169    //open file
2170    int fdout = open( file_path, (O_CREAT | O_RDWR), (S_IWUSR | S_IRUSR) );
2171    if (fdout < 0) 
2172    {
2173        perror("open");
2174        exit(1);
2175    }
2176
2177    //reinitialise the file
2178    if (ftruncate(fdout, 0)) 
2179    {
2180        perror("truncate");
2181        exit(1);
2182    }
2183
2184    #if XML_PARSER_DEBUG
2185    printf("%s\n", file_path);
2186    #endif
2187
2188    return fdout;
2189}
2190
2191
2192/////////////////////////////////////
2193void buildBin(const char * file_path) 
2194{
2195    unsigned int length;
2196
2197    int fdout = open_file(file_path);
2198
2199#if XML_PARSER_DEBUG
2200printf("Building map.bin for %s\n", header->name);
2201printf("signature = %x\n", header->signature);
2202printf("clusters  = %d\n", header->clusters);
2203printf("vspaces   = %d\n", header->vspaces);
2204printf("psegs     = %d\n", header->psegs);
2205printf("vobjs     = %d\n", header->vobjs);
2206printf("vsegs     = %d\n", header->vsegs);
2207printf("tasks     = %d\n", header->tasks);
2208printf("procs     = %d\n", header->procs);
2209printf("irqs      = %d\n", header->irqs);
2210printf("coprocs   = %d\n", header->coprocs);
2211printf("periphs   = %d\n", header->periphs);
2212#endif
2213
2214    // write header to binary file
2215    length = write(fdout, (char *) header, sizeof(mapping_header_t));
2216    if (length != sizeof(mapping_header_t)) 
2217    {
2218        printf("write header error : length = %d \n", length);
2219        exit(1);
2220    }
2221
2222    // write clusters
2223    BuildTable(fdout, "cluster", cluster_index, sizeof(mapping_cluster_t), (char **) cluster);
2224    // write psegs
2225    BuildTable(fdout, "pseg", pseg_index, sizeof(mapping_pseg_t), (char **) pseg);
2226    // write vspaces
2227    BuildTable(fdout, "vspace", vspace_index, sizeof(mapping_vspace_t), (char **) vspace);
2228    // write vsegs
2229    BuildTable(fdout, "vseg", vseg_index, sizeof(mapping_vseg_t), (char **) vseg);
2230    // write vobjs
2231    BuildTable(fdout, "vobj", vobj_index, sizeof(mapping_vobj_t), (char **) vobj);
2232    // write tasks array
2233    BuildTable(fdout, "task", task_index, sizeof(mapping_task_t), (char **) task);
2234    //building procs array
2235    BuildTable(fdout, "proc", proc_index, sizeof(mapping_proc_t), (char **) proc);
2236    //building irqs array
2237    BuildTable(fdout, "irq", irq_index, sizeof(mapping_irq_t), (char **) irq);
2238    //building coprocs array
2239    BuildTable(fdout, "coproc", coproc_index, sizeof(mapping_coproc_t), (char **) coproc);
2240    //building cp_ports array
2241    BuildTable(fdout, "cp_port", cp_port_index, sizeof(mapping_cp_port_t),(char **) cp_port);
2242    //building periphs array
2243    BuildTable(fdout, "periph", periph_index, sizeof(mapping_periph_t), (char **) periph);
2244
2245    close(fdout);
2246
2247} // end buildBin()
2248
2249
2250///////////////////////////////////////////////////////////////////////
2251// this function set the value the vobj_id fiels of all cp_ports
2252///////////////////////////////////////////////////////////////////////
2253void prepareBuild() 
2254{
2255    unsigned int i;
2256    //asign for all cp_ports the correct vspaceid and vobjid
2257    for (i = 0; i < cp_port_index; i++) {
2258        int vspace_id = getVspaceId(cp_port_vobj_ref[i]->vspace_name);
2259        if (vspace_id < 0) {
2260            printf("[XML ERROR] illegal  <vspacename> for cp_port %d,\n", i);
2261            exit(1);
2262        }
2263        cp_port[i]->vspaceid = vspace_id;
2264
2265        int vobj_id = getVobjLocId(vspace_id, cp_port_vobj_ref[i]->vobj_name, vspace[vspace_id]->vobjs);
2266        if (vobj_id >= 0) {
2267
2268#if XML_PARSER_DEBUG
2269            printf("\ncp_port = %d\n", i);
2270            printf("      vspace_name  = %s\n", cp_port_vobj_ref[i]->vspace_name);
2271            printf("      vobj_name    = %s\n", cp_port_vobj_ref[i]->vobj_name);
2272            printf("      vobj_index   = %d\n", vobj_id);
2273#endif
2274            cp_port[i]->mwmr_vobjid = vobj_id;
2275
2276            assert((vobj[ vspace[vspace_id]->vobj_offset + vobj_id]->type == VOBJ_TYPE_MWMR)
2277                    && "coproc ports have to refer to a vobj of type MWMR");
2278        }
2279        else {
2280            printf("[XML ERROR] illegal  <vobjname> for cp_port %d,\n", i);
2281            exit(1);
2282        }
2283    }
2284}
2285
2286//////////////////////////////////////////
2287void file_write(int fdout, char * towrite) 
2288{
2289    unsigned int size = strlen(towrite);
2290    if (size != write(fdout, towrite, size)) 
2291    {
2292        printf("file_write error");
2293        exit(1);
2294    }
2295}
2296
2297//////////////////////////////////////////////////
2298void def_int_write(int fdout, char * def, int num) 
2299{
2300    char  buf[64];
2301    sprintf(buf, "#define\t %s  %d\n", def, num);
2302    file_write(fdout, buf);
2303}
2304
2305//////////////////////////////////////////////////
2306void def_hex_write(int fdout, char * def, int num) 
2307{
2308    char  buf[64];
2309    sprintf(buf, "#define\t %s  0x%x\n", def, num);
2310    file_write(fdout, buf);
2311}
2312
2313///////////////////////////////////
2314void  genHd(const char * file_path) 
2315{
2316    int fdout = open_file(file_path);
2317
2318    char prol[80];
2319    sprintf(prol, "/* Generated from file %s.xml */\n\n",header->name);
2320
2321    char * ifdef  = "#ifndef _HARD_CONFIG_H\n#define _HARDD_CONFIG_H\n\n";
2322    char * epil   = "\n#endif //_HARD_CONFIG_H";
2323
2324    file_write(fdout, prol);
2325    file_write(fdout, ifdef);
2326
2327    def_int_write(fdout, "CLUSTER_X         ", cluster_x);
2328    def_int_write(fdout, "CLUSTER_Y         ", cluster_y);
2329    def_int_write(fdout, "NB_CLUSTERS       ", cluster_index);
2330    def_int_write(fdout, "NB_PROCS_MAX      ", nb_proc_max);
2331    def_int_write(fdout, "NB_TASKS_MAX      ", nb_tasks_max);
2332
2333    file_write(fdout, "\n");
2334
2335    def_int_write(fdout, "NB_TIM_CHANNELS   ", tim_channels);
2336    def_int_write(fdout, "NB_DMA_CHANNELS   ", dma_channels);
2337
2338    file_write(fdout, "\n");
2339
2340    def_int_write(fdout, "NB_TTY_CHANNELS   ", tty_channels);
2341    def_int_write(fdout, "NB_IOC_CHANNELS   ", ioc_channels);
2342    def_int_write(fdout, "NB_NIC_CHANNELS   ", nic_channels);
2343    def_int_write(fdout, "NB_CMA_CHANNELS   ", cma_channels);
2344
2345    file_write(fdout, "\n");
2346
2347    def_int_write(fdout, "USE_XICU          ", use_xcu);
2348    def_int_write(fdout, "USE_IOB           ", use_iob);
2349
2350    file_write(fdout, epil);
2351
2352    close(fdout);
2353}
2354
2355////////////////////////////////////////////////////////
2356void ld_write(int fdout, char * seg, unsigned int addr) 
2357{
2358    char buf[64];
2359    sprintf(buf, "%s = 0x%x;\n", seg, addr);
2360    file_write(fdout, buf);
2361}
2362
2363//////////////////////////////////
2364void genLd(const char * file_path) 
2365{
2366    int          fdout = open_file(file_path);
2367    unsigned int count = 0;
2368    unsigned int vseg_id;
2369
2370    char prol[80];
2371    sprintf(prol, "/* Generated from file %s.xml */\n\n",header->name);
2372
2373    file_write(fdout, prol);
2374
2375    // boot and kernel segments
2376    for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++)
2377    {
2378        if ( strcmp(vseg[vseg_id]->name, "seg_boot_code") == 0 )
2379        {
2380            ld_write(fdout, "seg_boot_code_base      ",  vseg[vseg_id]->vbase);
2381            count++;
2382        }
2383        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_data") == 0 )
2384        {
2385            ld_write(fdout, "seg_boot_data_base      ",  vseg[vseg_id]->vbase);
2386            count++;
2387        }
2388        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_stack") == 0 )
2389        {
2390            ld_write(fdout, "seg_boot_stack_base     ",  vseg[vseg_id]->vbase);
2391            count++;
2392        }
2393        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_mapping") == 0 )
2394        {
2395            ld_write(fdout, "seg_mapping_base        ",  vseg[vseg_id]->vbase);
2396            count++;
2397        }
2398        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_code") == 0 )
2399        {
2400            ld_write(fdout, "seg_kernel_code_base    ",  vseg[vseg_id]->vbase);
2401            count++;
2402        }
2403        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_data") == 0 )
2404        {
2405            ld_write(fdout, "seg_kernel_data_base    ",  vseg[vseg_id]->vbase);
2406            count++;
2407        }
2408        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_uncdata") == 0 )
2409        {
2410            ld_write(fdout, "seg_kernel_uncdata_base ",  vseg[vseg_id]->vbase);
2411            count++;
2412        }
2413        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_init") == 0 )
2414        {
2415            ld_write(fdout, "seg_kernel_init_base    ",  vseg[vseg_id]->vbase);
2416            count++;
2417        }
2418    }
2419    if ( count != 8 )
2420    { 
2421        printf ("[XML ERROR] Missing Boot or Kernel vseg : only %d\n", count);
2422        printf ("Mandatory segments are :\n");
2423        printf (" - seg_boot_code\n");
2424        printf (" - seg_boot_data\n");
2425        printf (" - seg_boot_stack\n");
2426        printf (" - seg_boot_mapping\n");
2427        printf (" - seg_kernel_code\n");
2428        printf (" - seg_kernel_data\n");
2429        printf (" - seg_kernel_uncdata\n");
2430        printf (" - seg_kernel_init\n");
2431    }
2432
2433    file_write(fdout, "\n");
2434
2435    // fill the peripheral base address array
2436    set_periph_vbase_array();
2437
2438    // non replicated peripherals
2439    ld_write(fdout, "seg_cma_base            ",   periph_vbase_array[PERIPH_TYPE_CMA]);
2440    ld_write(fdout, "seg_ioc_base            ",   periph_vbase_array[PERIPH_TYPE_IOC]);
2441    ld_write(fdout, "seg_tty_base            ",   periph_vbase_array[PERIPH_TYPE_TTY]);
2442    ld_write(fdout, "seg_fbf_base            ",   periph_vbase_array[PERIPH_TYPE_FBF]);
2443    ld_write(fdout, "seg_nic_base            ",   periph_vbase_array[PERIPH_TYPE_NIC]);
2444    ld_write(fdout, "seg_iob_base            ",   periph_vbase_array[PERIPH_TYPE_IOB]);
2445    ld_write(fdout, "seg_gcd_base            ",   periph_vbase_array[PERIPH_TYPE_GCD]);
2446    ld_write(fdout, "seg_sim_base            ",   periph_vbase_array[PERIPH_TYPE_SIM]);
2447
2448    file_write(fdout, "\n");
2449
2450    // replicated peripherals
2451    ld_write(fdout, "seg_xcu_base            ",   periph_vbase_array[PERIPH_TYPE_XCU]);
2452    ld_write(fdout, "seg_icu_base            ",   periph_vbase_array[PERIPH_TYPE_ICU]);
2453    ld_write(fdout, "seg_tim_base            ",   periph_vbase_array[PERIPH_TYPE_TIM]);
2454    ld_write(fdout, "seg_dma_base            ",   periph_vbase_array[PERIPH_TYPE_DMA]);
2455    ld_write(fdout, "seg_mmc_base            ",   periph_vbase_array[PERIPH_TYPE_MMC]);
2456
2457    file_write(fdout, "\n");
2458
2459    ld_write(fdout, "vseg_cluster_increment  ",   header->increment);
2460
2461    close(fdout);
2462}
2463
2464//////////////////////////////////////////////////////
2465char * buildPath(const char * path, const char * name) 
2466{
2467    char * res = calloc(strlen(path) + strlen(name) + 1, 1);
2468    strcat(res, path);
2469    strcat(res, "/");
2470    strcat(res, name);
2471    return res; 
2472}
2473
2474
2475//////////////////////////////////
2476int main(int argc, char * argv[]) 
2477{
2478    if (argc < 3) {
2479        printf("Usage: xml2bin <input_file_path> <output_path>\n");
2480        return 1;
2481    }
2482
2483    struct stat dir_st;
2484    if (stat( argv[2], &dir_st)) {
2485        perror("bad path");
2486        exit(1);
2487    }
2488
2489    if ((dir_st.st_mode & S_IFDIR) == 0) {
2490        printf("path is not a dir: %s", argv[2] );
2491        exit(1);
2492    }
2493
2494    char * map_path = buildPath(argv[2], "map.bin"); 
2495    char * ld_path = buildPath(argv[2], "giet_vsegs.ld"); 
2496    char * hd_path = buildPath(argv[2], "hard_config.h"); 
2497
2498    LIBXML_TEST_VERSION;
2499
2500    int status;
2501    xmlTextReaderPtr reader = xmlReaderForFile(argv[1], NULL, 0);
2502
2503    if (reader != NULL) 
2504    {
2505        status = xmlTextReaderRead (reader);
2506        while (status == 1) 
2507        {
2508            const char * tag = (const char *) xmlTextReaderConstName(reader);
2509
2510            if (strcmp(tag, "mapping_info") == 0) 
2511            { 
2512                headerNode(reader);
2513                prepareBuild();
2514                buildBin(map_path);
2515                genHd(hd_path);
2516                genLd(ld_path);
2517            }
2518            else 
2519            {
2520                printf("[XML ERROR] Wrong file type: \"%s\"\n", argv[1]);
2521                return 1;
2522            }
2523            status = xmlTextReaderRead(reader);
2524        }
2525        xmlFreeTextReader(reader);
2526
2527        if (status != 0) 
2528        {
2529            printf("[XML ERROR] Wrong Syntax in \"%s\" file\n", argv[1]);
2530            return 1;
2531        }
2532    }
2533    return 0;
2534} // end main()
2535
2536
2537// Local Variables:
2538// tab-width: 4
2539// c-basic-offset: 4
2540// c-file-offsets:((innamespace . 0)(inline-open . 0))
2541// indent-tabs-mode: nil
2542// End:
2543// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
2544
Note: See TracBrowser for help on using the repository browser.