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

Last change on this file since 306 was 306, checked in by alain, 10 years ago

Few modifications in XML format to support the PYTHON interface.

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