source: soft/giet_vm/giet_xml/xml_parser.c @ 258

Last change on this file since 258 was 258, checked in by alain, 11 years ago

This is a major release, including a deep restructuration of code.
The main evolutions are

  • use of the Tsar preloader to load the GIET boot-loader from disk
  • introduction of a FAT32 file system library,
  • use of this fat32 library by the boot-loader to load the map.bin data structure, and the various .elf files
  • reorganisation of drivers (one file per peripheral).
  • introduction of drivers for new peripherals: vci_chbuf_dma and vci_multi_ahci.
  • introduction of a new physical memory allocator in the boot code.

This release has been tested on the tsar_generic_iob architecture,
for the two following mappings: 4c_1p_iob_four.xml and 4c_1p_iob_sort.xml

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