source: soft/giet_vm/giet_python/mapping.py @ 739

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

Modify genmap to directly control the coprocessor type
using arguments defined in the Makefile.

  • Property svn:executable set to *
File size: 101.9 KB
Line 
1#!/usr/bin/env python
2
3import sys
4
5###################################################################################
6#   file   : giet_mapping.py
7#   date   : april 2014
8#   author : Alain Greiner
9###################################################################################
10#  This file contains the classes required to define a mapping for the GIET_VM.
11# - A 'Mapping' contains a set of 'Cluster'   (hardware architecture)
12#                        a set of 'Vseg'      (kernel global virtual segments)
13#                        a set of 'Vspace'    (one or several user applications)
14# - A 'Cluster' contains a set of 'Pseg'      (physical segments in cluster)
15#                        a set of 'Proc'      (processors in cluster)
16#                        a set of 'Periph'    (peripherals in cluster)
17# - A 'Vspace' contains  a set of 'Vseg'      (user virtual segments)
18#                        a set of 'Thread'    (POSIX thread)
19# - A 'Periph' contains  a set of 'Irq'       (only for XCU and PIC types )
20###################################################################################
21# Implementation Note
22# The objects used to describe a mapping are distributed in the PYTHON structure:
23# For example the psegs set is split in several subsets (one subset per cluster),
24# or the threads set is split in several subsets (one subset per vspace), etc...
25# In the C binary data structure used by the giet_vm, all objects of same type
26# are stored in a linear array (one single array for all psegs for example).
27# For all objects, we compute and store in the PYTHON object  a "global index"
28# corresponding to the index in this global array, and this index can be used as
29# a pseudo-pointer to identify a specific object of a given type.
30###################################################################################
31
32###################################################################################
33# Various constants
34###################################################################################
35
36PADDR_WIDTH       = 40            # number of bits for physical address
37X_WIDTH           = 4             # number of bits encoding x coordinate
38Y_WIDTH           = 4             # number of bits encoding y coordinate
39P_WIDTH           = 4             # number of bits encoding local proc_id
40VPN_ANTI_MASK     = 0x00000FFF    # mask vaddr to get offset in small page
41BPN_MASK          = 0xFFE00000    # mask vaddr to get the BPN in big page
42PERI_INCREMENT    = 0x10000       # virtual address increment for replicated vsegs
43RESET_ADDRESS     = 0xBFC00000    # Processor wired boot_address
44MAPPING_SIGNATURE = 0xDACE2014    # Magic number indicating a valid C BLOB
45
46###################################################################################
47# These lists must be consistent with values defined in
48# mapping_info.h / xml_driver.c /xml_parser.c
49###################################################################################
50PERIPHTYPES =    [
51                  'CMA',
52                  'DMA',
53                  'FBF',
54                  'IOB',
55                  'IOC',
56                  'MMC',
57                  'MWR',
58                  'NIC',
59                  'ROM',
60                  'SIM',
61                  'TIM',
62                  'TTY',
63                  'XCU',
64                  'PIC',
65                  'DROM',
66                 ]
67
68IOCSUBTYPES =    [
69                  'BDV',
70                  'HBA',
71                  'SDC',
72                  'SPI',
73                 ]
74
75MWRSUBTYPES =    [
76                  'CPY',
77                  'GCD',
78                  'DCT',
79                 ]
80   
81###################################################################################
82# These lists must be consistent with values defined in
83# irq_handler.c / irq_handler.h / xml_driver.c / xml_parser.c
84###################################################################################
85IRQTYPES =       [
86                  'HWI',
87                  'WTI',
88                  'PTI',
89                 ]
90
91ISRTYPES =       [
92                  'ISR_DEFAULT',
93                  'ISR_TICK',
94                  'ISR_TTY_RX',
95                  'ISR_TTY_TX',
96                  'ISR_BDV',
97                  'ISR_TIMER',
98                  'ISR_WAKUP',
99                  'ISR_NIC_RX',
100                  'ISR_NIC_TX',
101                  'ISR_CMA',
102                  'ISR_MMC',
103                  'ISR_DMA',
104                  'ISR_SDC',
105                  'ISR_MWR',
106                  'ISR_HBA',
107                  'ISR_SPI',
108                 ]
109
110VSEGTYPES =      [
111                  'ELF',
112                  'BLOB',
113                  'PTAB',
114                  'PERI',
115                  'BUFFER',
116                  'SCHED',     
117                  'HEAP',
118                 ]
119
120VSEGMODES =      [
121                  '____',
122                  '___U',
123                  '__W_',
124                  '__WU',
125                  '_X__',
126                  '_X_U',
127                  '_XW_',
128                  '_XWU',
129                  'C___',
130                  'C__U',
131                  'C_W_',
132                  'C_WU',
133                  'CX__',
134                  'CX_U',
135                  'CXW_',
136                  'CXWU',
137                 ]
138
139PSEGTYPES =      [
140                  'RAM',
141                  'PERI',
142                 ]
143
144###################################################################################
145class Mapping( object ):
146###################################################################################
147    def __init__( self,
148                  name,                            # mapping name
149                  x_size,                          # number of clusters in a row
150                  y_size,                          # number of clusters in a column
151                  nprocs,                          # max number of processors per cluster
152                  x_width        = X_WIDTH,        # number of bits encoding x coordinate
153                  y_width        = Y_WIDTH,        # number of bits encoding y coordinate
154                  p_width        = P_WIDTH,        # number of bits encoding lpid
155                  paddr_width    = PADDR_WIDTH,    # number of bits for physical address
156                  coherence      = 1,              # hardware cache coherence if non-zero
157                  irq_per_proc   = 1,              # number or IRQs from XCU to processor
158                  use_ramdisk    = False,          # use ramdisk when true
159                  x_io           = 0,              # cluster_io x coordinate
160                  y_io           = 0,              # cluster_io y coordinate
161                  peri_increment = PERI_INCREMENT, # address increment for globals
162                  reset_address  = RESET_ADDRESS,  # Processor wired boot_address
163                  ram_base       = 0,              # RAM physical base in cluster[0,0]
164                  ram_size       = 0 ):            # RAM size per cluster (bytes)
165
166        assert ( x_size <= (1<<X_WIDTH) )
167        assert ( y_size <= (1<<Y_WIDTH) )
168        assert ( nprocs <= (1<<P_WIDTH) )
169
170        self.signature      = MAPPING_SIGNATURE
171        self.name           = name
172        self.name           = name
173        self.paddr_width    = paddr_width
174        self.coherence      = coherence
175        self.x_size         = x_size
176        self.y_size         = y_size
177        self.nprocs         = nprocs
178        self.x_width        = x_width
179        self.y_width        = y_width
180        self.p_width        = p_width
181        self.irq_per_proc   = irq_per_proc
182        self.use_ramdisk    = use_ramdisk
183        self.x_io           = x_io
184        self.y_io           = y_io
185        self.peri_increment = peri_increment
186        self.reset_address  = reset_address
187        self.ram_base       = ram_base
188        self.ram_size       = ram_size
189
190        self.total_vspaces  = 0
191        self.total_globals  = 0
192        self.total_psegs    = 0
193        self.total_vsegs    = 0
194        self.total_threads  = 0
195        self.total_procs    = 0
196        self.total_irqs     = 0
197        self.total_periphs  = 0
198
199        self.clusters       = []
200        self.globs          = []
201        self.vspaces        = []
202
203        for x in xrange( self.x_size ):
204            for y in xrange( self.y_size ):
205                cluster = Cluster( x , y )
206                cluster.index = (x * self.y_size) + y
207                self.clusters.append( cluster )
208
209        return
210
211    ##########################    add a ram pseg in a cluster
212    def addRam( self,
213                name,                  # pseg name
214                base,                  # pseg base address
215                size ):                # pseg length (bytes)
216
217        # computes cluster index and coordinates from the base address
218        paddr_lsb_width = self.paddr_width - self.x_width - self.y_width
219        cluster_xy = base >> paddr_lsb_width
220        x          = cluster_xy >> (self.y_width);
221        y          = cluster_xy & ((1 << self.y_width) - 1)
222        cluster_id = (x * self.y_size) + y
223
224        assert (base & VPN_ANTI_MASK) == 0
225
226        assert (x < self.x_size) and (y < self.y_size)
227
228        assert ( (base & ((1<<paddr_lsb_width)-1)) == self.ram_base )
229
230        assert ( size == self.ram_size )
231
232        # add one pseg in the mapping
233        pseg = Pseg( name, base, size, x, y, 'RAM' )
234        self.clusters[cluster_id].psegs.append( pseg )
235        pseg.index = self.total_psegs
236        self.total_psegs += 1
237
238        return pseg
239
240    ##########################   add a peripheral and the associated pseg in a cluster
241    def addPeriph( self,
242                   name,               # associated pseg name
243                   base,               # associated pseg base address
244                   size,               # associated pseg length (bytes)
245                   ptype,              # peripheral type
246                   subtype  = 'NONE',  # peripheral subtype
247                   channels = 1,       # number of channels
248                   arg0     = 0,       # optional argument (semantic depends on ptype)
249                   arg1     = 0,       # optional argument (semantic depends on ptype)
250                   arg2     = 0,       # optional argument (semantic depends on ptype)
251                   arg3     = 0 ):     # optional argument (semantic depends on ptype)
252
253        # computes cluster index and coordinates from the base address
254        cluster_xy = base >> (self.paddr_width - self.x_width - self.y_width)
255        x          = cluster_xy >> (self.y_width);
256        y          = cluster_xy & ((1 << self.y_width) - 1)
257        cluster_id = (x * self.y_size) + y
258
259        assert (x < self.x_size) and (y < self.y_size)
260
261        assert (base & VPN_ANTI_MASK) == 0
262
263        assert ptype in PERIPHTYPES
264
265        if (ptype == 'IOC'): assert subtype in IOCSUBTYPES
266        if (ptype == 'MWR'): assert subtype in MWRSUBTYPES
267
268        # add one pseg into mapping
269        pseg = Pseg( name, base, size, x, y, 'PERI' )
270        self.clusters[cluster_id].psegs.append( pseg )
271        pseg.index = self.total_psegs
272        self.total_psegs += 1
273
274        # add one periph into mapping
275        periph = Periph( pseg, ptype, subtype, channels, arg0, arg1, arg2, arg3 )
276        self.clusters[cluster_id].periphs.append( periph )
277        periph.index = self.total_periphs
278        self.total_periphs += 1
279
280        return periph
281
282    ################################   add an IRQ in a peripheral
283    def addIrq( self,
284                periph,                # peripheral containing IRQ (PIC or XCU)
285                index,                 # peripheral input port index
286                src,                   # interrupt source peripheral
287                isrtype,               # ISR type
288                channel = 0 ):         # channel for multi-channels ISR
289
290        assert isrtype in ISRTYPES
291
292        assert index < 32
293
294        # add one irq into mapping
295        irq = Irq( 'HWI', index , isrtype, channel )
296        periph.irqs.append( irq )
297        irq.index = self.total_irqs
298        self.total_irqs += 1
299
300        # pointer from the source to the interrupt controller peripheral
301        if src.irq_ctrl == None: src.irq_ctrl = periph
302        if src.irq_ctrl != periph:
303            print '[genmap error] in addIrq():'
304            print '    two different interrupt controller for the same peripheral'
305            sys.exit(1)
306
307        return irq
308
309    ##########################    add a processor in a cluster
310    def addProc( self,
311                 x,                    # cluster x coordinate
312                 y,                    # cluster y coordinate
313                 lpid ):               # processor local index
314
315        assert (x < self.x_size) and (y < self.y_size)
316
317        cluster_id = (x * self.y_size) + y
318
319        # add one proc into mapping
320        proc = Processor( x, y, lpid )
321        self.clusters[cluster_id].procs.append( proc )
322        proc.index = self.total_procs
323        self.total_procs += 1
324
325        return proc
326
327    ############################    add one global vseg into mapping
328    def addGlobal( self, 
329                   name,               # vseg name
330                   vbase,              # virtual base address
331                   length,             # vseg length (bytes)
332                   mode,               # CXWU flags
333                   vtype,              # vseg type
334                   x,                  # destination x coordinate
335                   y,                  # destination y coordinate
336                   pseg,               # destination pseg name
337                   identity = False,   # identity mapping required if true
338                   local    = False,   # only mapped in local PTAB if true
339                   big      = False,   # to be mapped in a big physical page
340                   binpath  = '' ):    # pathname for binary code if required
341
342        # two global vsegs must not overlap if they have different names
343        for prev in self.globs:
344            if ( ((prev.vbase + prev.length) > vbase ) and 
345                 ((vbase + length) > prev.vbase) and
346                 (prev.name[0:15] != name[0:15]) ):
347                print '[genmap error] in addGlobal()'
348                print '    global vseg %s overlap %s' % (name, prev.name)
349                print '    %s : base = %x / size = %x' %(name, vbase, length)
350                print '    %s : base = %x / size = %x' %(prev.name, prev.vbase, prev.length)
351                sys.exit(1)
352
353        # add one vseg into mapping
354        vseg = Vseg( name, vbase, length, mode, vtype, x, y, pseg, 
355                     identity = identity, local = local, big = big, binpath = binpath )
356
357        self.globs.append( vseg )
358        self.total_globals += 1
359        vseg.index = self.total_vsegs
360        self.total_vsegs += 1
361
362        return
363
364    ################################    add a vspace into mapping
365    def addVspace( self,
366                   name,                # vspace name
367                   startname,           # name of vseg containing start_vector
368                   active = False ):    # default value is not active at boot
369
370        # add one vspace into mapping
371        vspace = Vspace( name, startname, active )
372        self.vspaces.append( vspace )
373        vspace.index = self.total_vspaces
374        self.total_vspaces += 1
375
376        return vspace
377
378    #################################   add a private vseg in a vspace
379    def addVseg( self,
380                 vspace,                # vspace containing the vseg
381                 name,                  # vseg name
382                 vbase,                 # virtual base address
383                 length,                # vseg length (bytes)
384                 mode,                  # CXWU flags
385                 vtype,                 # vseg type
386                 x,                     # destination x coordinate
387                 y,                     # destination y coordinate
388                 pseg,                  # destination pseg name
389                 local    = False,      # only mapped in local PTAB if true
390                 big      = False,      # to be mapped in a big physical page
391                 binpath  = '' ):       # pathname for binary code
392
393        assert mode in VSEGMODES
394
395        assert vtype in VSEGTYPES
396
397        assert (x < self.x_size) and (y < self.y_size)
398
399        # add one vseg into mapping
400        vseg = Vseg( name, vbase, length, mode, vtype, x, y, pseg, 
401                     identity = False, local = local, big = big, binpath = binpath )
402        vspace.vsegs.append( vseg )
403        vseg.index = self.total_vsegs
404        self.total_vsegs += 1
405
406        return vseg
407
408    ################################    add a thread in a vspace
409    def addThread( self,
410                   vspace,                # vspace containing thread
411                   name,                  # thread name
412                   is_main,               # Boolean (one thread per vspace)
413                   x,                     # destination x coordinate
414                   y,                     # destination y coordinate
415                   p,                     # destination processor local index
416                   stackname,             # name of vseg containing stack
417                   heapname,              # name of vseg containing heap
418                   startid ):             # index in start_vector
419
420        assert x < self.x_size
421        assert y < self.y_size
422        assert p < self.nprocs
423
424        # add one thread into mapping
425        thread = Thread( name, is_main, x, y, p, stackname, heapname, startid )
426        vspace.threads.append( thread )
427        thread.index = self.total_threads
428        self.total_threads += 1
429
430        return thread
431
432    #################################
433    def str2bytes( self, nbytes, s ):    # string => nbytes_packed byte array
434
435        byte_stream = bytearray()
436        length = len( s )
437        if length < (nbytes - 1):
438            for b in s:
439                byte_stream.append( b )
440            for x in xrange(nbytes-length):
441                byte_stream.append( '\0' )
442        else:
443            print '[genmap error] in str2bytes()'
444            print '    string %s too long' % s
445            sys.exit(1)
446
447        return byte_stream
448
449    ###################################
450    def int2bytes( self, nbytes, val ):    # integer => nbytes litle endian byte array
451
452        byte_stream = bytearray()
453        for n in xrange( nbytes ):
454            byte_stream.append( (val >> (n<<3)) & 0xFF )
455
456        return byte_stream
457
458    ################
459    def xml( self ):    # compute string for map.xml file generation
460
461        s = '<?xml version="1.0"?>\n\n'
462        s += '<mapping_info signature    = "0x%x"\n' % (self.signature)
463        s += '              name         = "%s"\n'   % (self.name)
464        s += '              x_size       = "%d"\n'   % (self.x_size)
465        s += '              y_size       = "%d"\n'   % (self.y_size)
466        s += '              x_width      = "%d"\n'   % (self.x_width)
467        s += '              y_width      = "%d"\n'   % (self.y_width)
468        s += '              irq_per_proc = "%d"\n'   % (self.irq_per_proc)
469        s += '              use_ramdisk  = "%d"\n'   % (self.use_ramdisk)
470        s += '              x_io         = "%d"\n'   % (self.x_io)
471        s += '              y_io         = "%d" >\n' % (self.y_io)
472        s += '\n'
473
474        s += '    <clusterset>\n'
475        for x in xrange ( self.x_size ):
476            for y in xrange ( self.y_size ):
477                cluster_id = (x * self.y_size) + y
478                s += self.clusters[cluster_id].xml()
479        s += '    </clusterset>\n'
480        s += '\n'
481
482        s += '    <globalset>\n'
483        for vseg in self.globs: s += vseg.xml()
484        s += '    </globalset>\n'
485        s += '\n'
486
487        s += '    <vspaceset>\n'
488        for vspace in self.vspaces: s += vspace.xml()
489        s += '    </vspaceset>\n'
490
491        s += '</mapping_info>\n'
492        return s
493
494    ##########################
495    def cbin( self, verbose ):     # C binary structure for map.bin file generation
496
497        byte_stream = bytearray()
498
499        # header
500        byte_stream += self.int2bytes(4,   self.signature)
501        byte_stream += self.int2bytes(4,   self.x_size)
502        byte_stream += self.int2bytes(4,   self.y_size)
503        byte_stream += self.int2bytes(4,   self.x_width)
504        byte_stream += self.int2bytes(4,   self.y_width)
505        byte_stream += self.int2bytes(4,   self.x_io)
506        byte_stream += self.int2bytes(4,   self.y_io)
507        byte_stream += self.int2bytes(4,   self.irq_per_proc)
508        byte_stream += self.int2bytes(4,   self.use_ramdisk)
509        byte_stream += self.int2bytes(4,   self.total_globals)
510        byte_stream += self.int2bytes(4,   self.total_vspaces)
511        byte_stream += self.int2bytes(4,   self.total_psegs)
512        byte_stream += self.int2bytes(4,   self.total_vsegs)
513        byte_stream += self.int2bytes(4,   self.total_threads)
514        byte_stream += self.int2bytes(4,   self.total_procs)
515        byte_stream += self.int2bytes(4,   self.total_irqs)
516        byte_stream += self.int2bytes(4,   self.total_periphs)
517        byte_stream += self.str2bytes(256, self.name)
518
519        if ( verbose ):
520            print '\n'
521            print 'name          = %s' % self.name
522            print 'signature     = %x' % self.signature
523            print 'x_size        = %d' % self.x_size
524            print 'y_size        = %d' % self.y_size
525            print 'x_width       = %d' % self.x_width
526            print 'y_width       = %d' % self.y_width
527            print 'x_io          = %d' % self.x_io
528            print 'y_io          = %d' % self.y_io
529            print 'irq_per_proc  = %d' % self.irq_per_proc
530            print 'use_ramdisk   = %d' % self.use_ramdisk
531            print 'total_globals = %d' % self.total_globals
532            print 'total_psegs   = %d' % self.total_psegs
533            print 'total_vsegs   = %d' % self.total_vsegs
534            print 'total_threads   = %d' % self.total_threads
535            print 'total_procs   = %d' % self.total_procs
536            print 'total_irqs    = %d' % self.total_irqs
537            print 'total_periphs = %d' % self.total_periphs
538            print '\n'
539
540        # clusters array
541        index = 0
542        for cluster in self.clusters:
543            byte_stream += cluster.cbin( self, verbose, index )
544            index += 1
545
546        if ( verbose ): print '\n'
547
548        # psegs array
549        index = 0
550        for cluster in self.clusters:
551            for pseg in cluster.psegs:
552                byte_stream += pseg.cbin( self, verbose, index, cluster )
553                index += 1
554
555        if ( verbose ): print '\n'
556
557        # vspaces array
558        index = 0
559        for vspace in self.vspaces:
560            byte_stream += vspace.cbin( self, verbose, index )
561            index += 1
562
563        if ( verbose ): print '\n'
564
565        # vsegs array
566        index = 0
567        for vseg in self.globs:
568            byte_stream += vseg.cbin( self, verbose, index )
569            index += 1
570        for vspace in self.vspaces:
571            for vseg in vspace.vsegs:
572                byte_stream += vseg.cbin( self, verbose, index )
573                index += 1
574
575        if ( verbose ): print '\n'
576
577        # threads array
578        index = 0
579        for vspace in self.vspaces:
580            for thread in vspace.threads:
581                byte_stream += thread.cbin( self, verbose, index, vspace )
582                index += 1
583
584        if ( verbose ): print '\n'
585
586        # procs array
587        index = 0
588        for cluster in self.clusters:
589            for proc in cluster.procs:
590                byte_stream += proc.cbin( self, verbose, index )
591                index += 1
592
593        if ( verbose ): print '\n'
594
595        # irqs array
596        index = 0
597        for cluster in self.clusters:
598            for periph in cluster.periphs:
599                for irq in periph.irqs:
600                    byte_stream += irq.cbin( self, verbose, index )
601                    index += 1
602
603        if ( verbose ): print '\n'
604
605        # periphs array
606        index = 0
607        for cluster in self.clusters:
608            for periph in cluster.periphs:
609                byte_stream += periph.cbin( self, verbose, index )
610                index += 1
611
612        return byte_stream
613    # end of cbin()
614
615    #######################################################################
616    def giet_vsegs( self ):      # compute string for giet_vsegs.ld file
617                                 # required by giet_vm compilation
618
619        # search the vsegs required for the giet_vsegs.ld
620        boot_code_found      = False
621        boot_data_found      = False
622        kernel_uncdata_found = False
623        kernel_data_found    = False
624        kernel_code_found    = False
625        kernel_init_found    = False
626        for vseg in self.globs:
627
628            if ( vseg.name[0:13] == 'seg_boot_code' ):
629                boot_code_vbase      = vseg.vbase
630                boot_code_size       = vseg.length
631                boot_code_found      = True
632
633            if ( vseg.name[0:13] == 'seg_boot_data' ):
634                boot_data_vbase      = vseg.vbase
635                boot_data_size       = vseg.length
636                boot_data_found      = True
637
638            if ( vseg.name[0:15] == 'seg_kernel_data' ):
639                kernel_data_vbase    = vseg.vbase
640                kernel_data_size     = vseg.length
641                kernel_data_found    = True
642
643            if ( vseg.name[0:15] == 'seg_kernel_code' ):
644                kernel_code_vbase    = vseg.vbase
645                kernel_code_size     = vseg.length
646                kernel_code_found    = True
647
648            if ( vseg.name[0:15] == 'seg_kernel_init' ):
649                kernel_init_vbase    = vseg.vbase
650                kernel_init_size     = vseg.length
651                kernel_init_found    = True
652
653        # check if all required vsegs have been found
654        if ( boot_code_found      == False ):
655             print '[genmap error] in giet_vsegs()'
656             print '    seg_boot_code vseg missing'
657             sys.exit()
658
659        if ( boot_data_found      == False ):
660             print '[genmap error] in giet_vsegs()'
661             print '    seg_boot_data vseg missing'
662             sys.exit()
663
664        if ( kernel_data_found    == False ):
665             print '[genmap error] in giet_vsegs()'
666             print '    seg_kernel_data vseg missing'
667             sys.exit()
668
669        if ( kernel_code_found    == False ):
670             print '[genmap error] in giet_vsegs()'
671             print '    seg_kernel_code vseg missing'
672             sys.exit()
673
674        if ( kernel_init_found    == False ):
675             print '[genmap error] in giet_vsegs()'
676             print '    seg_kernel_init vseg missing'
677             sys.exit()
678
679        # build string
680        s =  '/* Generated by genmap for %s */\n'  % self.name
681        s += '\n'
682
683        s += 'boot_code_vbase      = 0x%x;\n'   % boot_code_vbase
684        s += 'boot_code_size       = 0x%x;\n'   % boot_code_size
685        s += '\n'
686        s += 'boot_data_vbase      = 0x%x;\n'   % boot_data_vbase
687        s += 'boot_data_size       = 0x%x;\n'   % boot_data_size
688        s += '\n'
689        s += 'kernel_code_vbase    = 0x%x;\n'   % kernel_code_vbase
690        s += 'kernel_code_size     = 0x%x;\n'   % kernel_code_size
691        s += '\n'
692        s += 'kernel_data_vbase    = 0x%x;\n'   % kernel_data_vbase
693        s += 'kernel_data_size     = 0x%x;\n'   % kernel_data_size
694        s += '\n'
695        s += 'kernel_init_vbase    = 0x%x;\n'   % kernel_init_vbase
696        s += 'kernel_init_size     = 0x%x;\n'   % kernel_init_size
697        s += '\n'
698
699        return s
700
701    ######################################################################
702    def hard_config( self ):     # compute string for hard_config.h file
703                                 # required by
704                                 # - top.cpp compilation
705                                 # - giet_vm compilation
706                                 # - tsar_preloader compilation
707
708        nb_total_procs = 0
709
710        # for each peripheral type, define default values
711        # for pbase address, size, number of components, and channels
712        nb_cma       = 0
713        cma_channels = 0
714        seg_cma_base = 0xFFFFFFFF
715        seg_cma_size = 0
716
717        nb_dma       = 0
718        dma_channels = 0
719        seg_dma_base = 0xFFFFFFFF
720        seg_dma_size = 0
721
722        nb_fbf       = 0
723        fbf_channels = 0
724        seg_fbf_base = 0xFFFFFFFF
725        seg_fbf_size = 0
726        fbf_arg0     = 0
727        fbf_arg1     = 0
728
729        nb_iob       = 0
730        iob_channels = 0
731        seg_iob_base = 0xFFFFFFFF
732        seg_iob_size = 0
733
734        nb_ioc       = 0
735        ioc_channels = 0
736        seg_ioc_base = 0xFFFFFFFF
737        seg_ioc_size = 0
738        use_ioc_bdv  = False
739        use_ioc_sdc  = False
740        use_ioc_hba  = False
741        use_ioc_spi  = False
742
743        nb_mmc       = 0
744        mmc_channels = 0
745        seg_mmc_base = 0xFFFFFFFF
746        seg_mmc_size = 0
747
748        nb_mwr       = 0
749        mwr_channels = 0
750        seg_mwr_base = 0xFFFFFFFF
751        seg_mwr_size = 0
752        mwr_arg0     = 0
753        mwr_arg1     = 0
754        mwr_arg2     = 0
755        mwr_arg3     = 0
756        use_mwr_gcd  = False
757        use_mwr_dct  = False
758        use_mwr_cpy  = False
759
760        nb_nic       = 0
761        nic_channels = 0
762        seg_nic_base = 0xFFFFFFFF
763        seg_nic_size = 0
764
765        nb_pic       = 0
766        pic_channels = 0
767        seg_pic_base = 0xFFFFFFFF
768        seg_pic_size = 0
769
770        nb_rom       = 0
771        rom_channels = 0
772        seg_rom_base = 0xFFFFFFFF
773        seg_rom_size = 0
774
775        nb_sim       = 0
776        sim_channels = 0
777        seg_sim_base = 0xFFFFFFFF
778        seg_sim_size = 0
779
780        nb_tim       = 0
781        tim_channels = 0
782        seg_tim_base = 0xFFFFFFFF
783        seg_tim_size = 0
784
785        nb_tty       = 0
786        tty_channels = 0
787        seg_tty_base = 0xFFFFFFFF
788        seg_tty_size = 0
789
790        nb_xcu       = 0
791        xcu_channels = 0
792        seg_xcu_base = 0xFFFFFFFF
793        seg_xcu_size = 0
794        xcu_arg0     = 0
795
796        nb_drom       = 0
797        drom_channels = 0
798        seg_drom_base = 0xFFFFFFFF
799        seg_drom_size = 0
800
801        # get peripherals attributes
802        for cluster in self.clusters:
803            for periph in cluster.periphs:
804                if   ( periph.ptype == 'CMA' ):
805                    seg_cma_base = periph.pseg.base & 0xFFFFFFFF
806                    seg_cma_size = periph.pseg.size
807                    cma_channels = periph.channels
808                    nb_cma +=1
809
810                elif ( periph.ptype == 'DMA' ):
811                    seg_dma_base = periph.pseg.base & 0xFFFFFFFF
812                    seg_dma_size = periph.pseg.size
813                    dma_channels = periph.channels
814                    nb_dma +=1
815
816                elif ( periph.ptype == 'FBF' ):
817                    seg_fbf_base = periph.pseg.base & 0xFFFFFFFF
818                    seg_fbf_size = periph.pseg.size
819                    fbf_channels = periph.channels
820                    fbf_arg0     = periph.arg0
821                    fbf_arg1     = periph.arg1
822                    nb_fbf +=1
823
824                elif ( periph.ptype == 'IOB' ):
825                    seg_iob_base = periph.pseg.base & 0xFFFFFFFF
826                    seg_iob_size = periph.pseg.size
827                    iob_channels = periph.channels
828                    nb_iob +=1
829
830                elif ( periph.ptype == 'IOC' ):
831                    seg_ioc_base = periph.pseg.base & 0xFFFFFFFF
832                    seg_ioc_size = periph.pseg.size
833                    ioc_channels = periph.channels
834                    nb_ioc += 1
835                    if ( periph.subtype == 'BDV' ): use_ioc_bdv = True
836                    if ( periph.subtype == 'HBA' ): use_ioc_hba = True
837                    if ( periph.subtype == 'SDC' ): use_ioc_sdc = True
838                    if ( periph.subtype == 'SPI' ): use_ioc_spi = True
839
840                elif ( periph.ptype == 'MMC' ):
841                    seg_mmc_base = periph.pseg.base & 0xFFFFFFFF
842                    seg_mmc_size = periph.pseg.size
843                    mmc_channels = periph.channels
844                    nb_mmc +=1
845
846                elif ( periph.ptype == 'MWR' ):
847                    seg_mwr_base = periph.pseg.base & 0xFFFFFFFF
848                    seg_mwr_size = periph.pseg.size
849                    mwr_channels = periph.channels
850                    mwr_arg0     = periph.arg0
851                    mwr_arg1     = periph.arg1
852                    mwr_arg2     = periph.arg2
853                    mwr_arg3     = periph.arg3
854                    nb_mwr +=1
855                    if ( periph.subtype == 'GCD' ): use_mwr_gcd = True
856                    if ( periph.subtype == 'DCT' ): use_mwr_dct = True
857                    if ( periph.subtype == 'CPY' ): use_mwr_cpy = True
858
859                elif ( periph.ptype == 'ROM' ):
860                    seg_rom_base = periph.pseg.base & 0xFFFFFFFF
861                    seg_rom_size = periph.pseg.size
862                    rom_channels = periph.channels
863                    nb_rom +=1
864
865                elif ( periph.ptype == 'DROM' ):
866                    seg_drom_base = periph.pseg.base & 0xFFFFFFFF
867                    seg_drom_size = periph.pseg.size
868                    drom_channels = periph.channels
869                    nb_drom +=1
870
871                elif ( periph.ptype == 'SIM' ):
872                    seg_sim_base = periph.pseg.base & 0xFFFFFFFF
873                    seg_sim_size = periph.pseg.size
874                    sim_channels = periph.channels
875                    nb_sim +=1
876
877                elif ( periph.ptype == 'NIC' ):
878                    seg_nic_base = periph.pseg.base & 0xFFFFFFFF
879                    seg_nic_size = periph.pseg.size
880                    nic_channels = periph.channels
881                    nb_nic +=1
882
883                elif ( periph.ptype == 'PIC' ):
884                    seg_pic_base = periph.pseg.base & 0xFFFFFFFF
885                    seg_pic_size = periph.pseg.size
886                    pic_channels = periph.channels
887                    nb_pic +=1
888
889                elif ( periph.ptype == 'TIM' ):
890                    seg_tim_base = periph.pseg.base & 0xFFFFFFFF
891                    seg_tim_size = periph.pseg.size
892                    tim_channels = periph.channels
893                    nb_tim +=1
894
895                elif ( periph.ptype == 'TTY' ):
896                    seg_tty_base = periph.pseg.base & 0xFFFFFFFF
897                    seg_tty_size = periph.pseg.size
898                    tty_channels = periph.channels
899                    nb_tty +=1
900
901                elif ( periph.ptype == 'XCU' ):
902                    seg_xcu_base = periph.pseg.base & 0xFFFFFFFF
903                    seg_xcu_size = periph.pseg.size
904                    xcu_channels = periph.channels
905                    xcu_arg0     = periph.arg0
906                    xcu_arg1     = periph.arg1
907                    xcu_arg2     = periph.arg2
908                    nb_xcu +=1
909
910        # no more than two access to external peripherals
911        assert ( nb_fbf <= 2 )
912        assert ( nb_cma <= 2 )
913        assert ( nb_ioc <= 2 )
914        assert ( nb_nic <= 2 )
915        assert ( nb_tim <= 2 )
916        assert ( nb_tty <= 2 )
917        assert ( nb_pic <= 2 )
918
919        # one and only one type of IOC controller
920        nb_ioc_types = 0
921        if use_ioc_hba:       nb_ioc_types += 1
922        if use_ioc_bdv:       nb_ioc_types += 1
923        if use_ioc_sdc:       nb_ioc_types += 1
924        if use_ioc_spi:       nb_ioc_types += 1
925        if self.use_ramdisk:  nb_ioc_types += 1
926        assert ( nb_ioc_types == 1 )
927
928        # one and only one type of MWR controller
929        nb_mwr_types = 0
930        if use_mwr_gcd:       nb_mwr_types += 1
931        if use_mwr_dct:       nb_mwr_types += 1
932        if use_mwr_cpy:       nb_mwr_types += 1
933        if ( nb_mwr > 0 ) : assert ( nb_mwr_types == 1 )
934
935        # Compute total number of processors
936        for cluster in self.clusters:
937            nb_total_procs += len( cluster.procs )
938
939        # Compute physical addresses for BOOT vsegs
940        boot_mapping_found   = False
941        boot_code_found      = False
942        boot_data_found      = False
943        boot_stack_found     = False
944
945        for vseg in self.globs:
946            if ( vseg.name == 'seg_boot_mapping' ):
947                boot_mapping_base       = vseg.vbase
948                boot_mapping_size       = vseg.length
949                boot_mapping_identity   = vseg.identity
950                boot_mapping_found      = True
951
952            if ( vseg.name == 'seg_boot_code' ):
953                boot_code_base          = vseg.vbase
954                boot_code_size          = vseg.length
955                boot_code_identity      = vseg.identity
956                boot_code_found         = True
957
958            if ( vseg.name == 'seg_boot_data' ):
959                boot_data_base          = vseg.vbase
960                boot_data_size          = vseg.length
961                boot_data_identity      = vseg.identity
962                boot_data_found         = True
963
964            if ( vseg.name == 'seg_boot_stack' ):
965                boot_stack_base         = vseg.vbase
966                boot_stack_size         = vseg.length
967                boot_stack_identity     = vseg.identity
968                boot_stack_found        = True
969
970        # check that BOOT vsegs are found and identity mapping
971        if ( (boot_mapping_found == False) or (boot_mapping_identity == False) ):
972             print '[genmap error] in hard_config()'
973             print '    seg_boot_mapping missing or not identity mapping'
974             sys.exit()
975
976        if ( (boot_code_found == False) or (boot_code_identity == False) ):
977             print '[genmap error] in hard_config()'
978             print '    seg_boot_code missing or not identity mapping'
979             sys.exit()
980
981        if ( (boot_data_found == False) or (boot_data_identity == False) ):
982             print '[genmap error] in hard_config()'
983             print '    seg_boot_data missing or not identity mapping'
984             sys.exit()
985
986        if ( (boot_stack_found == False) or (boot_stack_identity == False) ):
987             print '[genmap error] in giet_vsegs()'
988             print '    seg_boot_stack missing or not identity mapping'
989             sys.exit()
990
991        # Search RAMDISK global vseg if required
992        seg_rdk_base =  0xFFFFFFFF
993        seg_rdk_size =  0
994        seg_rdk_found = False
995
996        if self.use_ramdisk:
997            for vseg in self.globs:
998                if ( vseg.name == 'seg_ramdisk' ):
999                    seg_rdk_base  = vseg.vbase
1000                    seg_rdk_size  = vseg.length
1001                    seg_rdk_found = True
1002
1003            if ( seg_rdk_found == False ):
1004                print 'Error in hard_config() "seg_ramdisk" not found'
1005                sys.exit(1)
1006
1007        # build string
1008        s =  '/* Generated by genmap for %s */\n'  % self.name
1009        s += '\n'
1010        s += '#ifndef HARD_CONFIG_H\n'
1011        s += '#define HARD_CONFIG_H\n'
1012        s += '\n'
1013
1014        s += '/* General platform parameters */\n'
1015        s += '\n'
1016        s += '#define X_SIZE                 %d\n'    % self.x_size
1017        s += '#define Y_SIZE                 %d\n'    % self.y_size
1018        s += '#define X_WIDTH                %d\n'    % self.x_width
1019        s += '#define Y_WIDTH                %d\n'    % self.y_width
1020        s += '#define P_WIDTH                %d\n'    % self.p_width
1021        s += '#define X_IO                   %d\n'    % self.x_io
1022        s += '#define Y_IO                   %d\n'    % self.y_io
1023        s += '#define NB_PROCS_MAX           %d\n'    % self.nprocs
1024        s += '#define IRQ_PER_PROCESSOR      %d\n'    % self.irq_per_proc
1025        s += '#define RESET_ADDRESS          0x%x\n'  % self.reset_address
1026        s += '#define NB_TOTAL_PROCS         %d\n'    % nb_total_procs
1027        s += '\n'
1028
1029        s += '/* Peripherals */\n'
1030        s += '\n'
1031        s += '#define NB_TTY_CHANNELS        %d\n'    % tty_channels
1032        s += '#define NB_IOC_CHANNELS        %d\n'    % ioc_channels
1033        s += '#define NB_NIC_CHANNELS        %d\n'    % nic_channels
1034        s += '#define NB_CMA_CHANNELS        %d\n'    % cma_channels
1035        s += '#define NB_TIM_CHANNELS        %d\n'    % tim_channels
1036        s += '#define NB_DMA_CHANNELS        %d\n'    % dma_channels
1037        s += '\n'
1038        s += '#define USE_XCU                %d\n'    % ( nb_xcu != 0 )
1039        s += '#define USE_DMA                %d\n'    % ( nb_dma != 0 )
1040        s += '\n'
1041        s += '#define USE_IOB                %d\n'    % ( nb_iob != 0 )
1042        s += '#define USE_PIC                %d\n'    % ( nb_pic != 0 )
1043        s += '#define USE_FBF                %d\n'    % ( nb_fbf != 0 )
1044        s += '#define USE_NIC                %d\n'    % ( nb_nic != 0 )
1045        s += '\n'
1046        s += '#define USE_IOC_BDV            %d\n'    % use_ioc_bdv
1047        s += '#define USE_IOC_SDC            %d\n'    % use_ioc_sdc
1048        s += '#define USE_IOC_HBA            %d\n'    % use_ioc_hba
1049        s += '#define USE_IOC_SPI            %d\n'    % use_ioc_spi
1050        s += '#define USE_IOC_RDK            %d\n'    % self.use_ramdisk
1051        s += '\n'
1052        s += '#define USE_MWR_GCD            %d\n'    % use_mwr_gcd
1053        s += '#define USE_MWR_DCT            %d\n'    % use_mwr_dct
1054        s += '#define USE_MWR_CPY            %d\n'    % use_mwr_cpy
1055        s += '\n'
1056        s += '#define FBUF_X_SIZE            %d\n'    % fbf_arg0
1057        s += '#define FBUF_Y_SIZE            %d\n'    % fbf_arg1
1058        s += '\n'
1059        s += '#define XCU_NB_HWI             %d\n'    % xcu_arg0
1060        s += '#define XCU_NB_PTI             %d\n'    % xcu_arg1
1061        s += '#define XCU_NB_WTI             %d\n'    % xcu_arg2
1062        s += '#define XCU_NB_OUT             %d\n'    % xcu_channels
1063        s += '\n'
1064        s += '#define MWR_TO_COPROC          %d\n'    % mwr_arg0
1065        s += '#define MWR_FROM_COPROC        %d\n'    % mwr_arg1
1066        s += '#define MWR_CONFIG             %d\n'    % mwr_arg2
1067        s += '#define MWR_STATUS             %d\n'    % mwr_arg3
1068        s += '\n'
1069
1070        s += '/* base addresses and sizes for physical segments */\n'
1071        s += '\n'
1072        s += '#define SEG_RAM_BASE           0x%x\n'  % self.ram_base
1073        s += '#define SEG_RAM_SIZE           0x%x\n'  % self.ram_size
1074        s += '\n'
1075        s += '#define SEG_CMA_BASE           0x%x\n'  % seg_cma_base
1076        s += '#define SEG_CMA_SIZE           0x%x\n'  % seg_cma_size
1077        s += '\n'
1078        s += '#define SEG_DMA_BASE           0x%x\n'  % seg_dma_base
1079        s += '#define SEG_DMA_SIZE           0x%x\n'  % seg_dma_size
1080        s += '\n'
1081        s += '#define SEG_FBF_BASE           0x%x\n'  % seg_fbf_base
1082        s += '#define SEG_FBF_SIZE           0x%x\n'  % seg_fbf_size
1083        s += '\n'
1084        s += '#define SEG_IOB_BASE           0x%x\n'  % seg_iob_base
1085        s += '#define SEG_IOB_SIZE           0x%x\n'  % seg_iob_size
1086        s += '\n'
1087        s += '#define SEG_IOC_BASE           0x%x\n'  % seg_ioc_base
1088        s += '#define SEG_IOC_SIZE           0x%x\n'  % seg_ioc_size
1089        s += '\n'
1090        s += '#define SEG_MMC_BASE           0x%x\n'  % seg_mmc_base
1091        s += '#define SEG_MMC_SIZE           0x%x\n'  % seg_mmc_size
1092        s += '\n'
1093        s += '#define SEG_MWR_BASE           0x%x\n'  % seg_mwr_base
1094        s += '#define SEG_MWR_SIZE           0x%x\n'  % seg_mwr_size
1095        s += '\n'
1096        s += '#define SEG_ROM_BASE           0x%x\n'  % seg_rom_base
1097        s += '#define SEG_ROM_SIZE           0x%x\n'  % seg_rom_size
1098        s += '\n'
1099        s += '#define SEG_SIM_BASE           0x%x\n'  % seg_sim_base
1100        s += '#define SEG_SIM_SIZE           0x%x\n'  % seg_sim_size
1101        s += '\n'
1102        s += '#define SEG_NIC_BASE           0x%x\n'  % seg_nic_base
1103        s += '#define SEG_NIC_SIZE           0x%x\n'  % seg_nic_size
1104        s += '\n'
1105        s += '#define SEG_PIC_BASE           0x%x\n'  % seg_pic_base
1106        s += '#define SEG_PIC_SIZE           0x%x\n'  % seg_pic_size
1107        s += '\n'
1108        s += '#define SEG_TIM_BASE           0x%x\n'  % seg_tim_base
1109        s += '#define SEG_TIM_SIZE           0x%x\n'  % seg_tim_size
1110        s += '\n'
1111        s += '#define SEG_TTY_BASE           0x%x\n'  % seg_tty_base
1112        s += '#define SEG_TTY_SIZE           0x%x\n'  % seg_tty_size
1113        s += '\n'
1114        s += '#define SEG_XCU_BASE           0x%x\n'  % seg_xcu_base
1115        s += '#define SEG_XCU_SIZE           0x%x\n'  % seg_xcu_size
1116        s += '\n'
1117        s += '#define SEG_RDK_BASE           0x%x\n'  % seg_rdk_base
1118        s += '#define SEG_RDK_SIZE           0x%x\n'  % seg_rdk_size
1119        s += '\n'
1120        s += '#define SEG_DROM_BASE          0x%x\n'  % seg_drom_base
1121        s += '#define SEG_DROM_SIZE          0x%x\n'  % seg_drom_size
1122        s += '\n'
1123        s += '#define PERI_CLUSTER_INCREMENT 0x%x\n'  % self.peri_increment
1124        s += '\n'
1125
1126        s += '/* physical base addresses for identity mapped vsegs */\n'
1127        s += '/* used by the GietVM OS                             */\n'
1128        s += '\n'
1129        s += '#define SEG_BOOT_MAPPING_BASE  0x%x\n'  % boot_mapping_base
1130        s += '#define SEG_BOOT_MAPPING_SIZE  0x%x\n'  % boot_mapping_size
1131        s += '\n'
1132        s += '#define SEG_BOOT_CODE_BASE     0x%x\n'  % boot_code_base
1133        s += '#define SEG_BOOT_CODE_SIZE     0x%x\n'  % boot_code_size
1134        s += '\n'
1135        s += '#define SEG_BOOT_DATA_BASE     0x%x\n'  % boot_data_base
1136        s += '#define SEG_BOOT_DATA_SIZE     0x%x\n'  % boot_data_size
1137        s += '\n'
1138        s += '#define SEG_BOOT_STACK_BASE    0x%x\n'  % boot_stack_base
1139        s += '#define SEG_BOOT_STACK_SIZE    0x%x\n'  % boot_stack_size
1140        s += '#endif\n'
1141
1142        return s
1143
1144    # end of hard_config()
1145
1146    #################################################################
1147    def linux_dts( self ):     # compute string for linux.dts file
1148                               # used for linux configuration
1149        # header
1150        s =  '/dts-v1/;\n'
1151        s += '\n'
1152        s += '/{\n'
1153        s += '  compatible = "tsar,%s";\n' % self.name
1154        s += '  #address-cells = <2>;\n'               # physical address on 64 bits
1155        s += '  #size-cells    = <1>;\n'               # segment size on 32 bits
1156        s += '  model = "%s";\n' % self.name
1157        s += '\n'
1158
1159        # linux globals arguments
1160        s += '  chosen {\n'
1161        s += '    linux,stdout-path = &tty;\n'
1162        s += '    bootargs = "console=tty0 console=ttyVTTY0 earlyprintk";\n'
1163        s += '  };\n\n'
1164
1165        # cpus (for each cluster)
1166        s += '  cpus {\n'
1167        s += '    #address-cells = <1>;\n'
1168        s += '    #size-cells    = <0>;\n'
1169
1170        for cluster in self.clusters:
1171            for proc in cluster.procs:
1172                x       = cluster.x
1173                y       = cluster.y
1174                l       = proc.lpid
1175                proc_id = (((x << self.y_width) + y) << self.p_width) + l
1176                s += '    cpu@%d_%d_%d {\n' %(x,y,l)
1177                s += '      device_type = "cpu";\n'
1178                s += '      compatible = "soclib,mips32el";\n'
1179                s += '      reg = <0x%x>;\n' % proc_id
1180                s += '    };\n'
1181                s += '\n'
1182
1183        s += '  };\n\n'
1184
1185        # devices (ram or peripheral) are grouped per cluster
1186        # the "compatible" attribute links a peripheral device
1187        # to one or several drivers identified by ("major","minor")
1188
1189        chosen_tty = False
1190        for cluster in self.clusters:
1191            x               = cluster.x
1192            y               = cluster.y
1193            found_xcu       = False
1194            found_pic       = False
1195
1196            s += '  /*** cluster[%d,%d] ***/\n\n' % (x,y)
1197
1198            # scan all psegs to find RAM in current cluster
1199            for pseg in cluster.psegs:
1200                if ( pseg.segtype == 'RAM' ):
1201                    msb  = pseg.base >> 32
1202                    lsb  = pseg.base & 0xFFFFFFFF
1203                    size = pseg.size
1204
1205                    s += %s@0x%x {\n' % (pseg.name, pseg.base)
1206                    s += '    device_type = "memory";\n'
1207                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1208                    s += '  };\n\n'
1209
1210            # scan all periphs to find XCU or PIC in current cluster
1211            for periph in cluster.periphs:
1212                msb     = periph.pseg.base >> 32
1213                lsb     = periph.pseg.base & 0xFFFFFFFF
1214                size    = periph.pseg.size
1215
1216                # search XCU (can be replicated)
1217                if ( (periph.ptype == 'XCU') ):
1218                    found_xcu     = True
1219
1220                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1221                    s += '    compatible = "soclib,vci_xicu","soclib,vci_xicu_timer";\n'
1222                    s += '    interrupt-controller;\n'
1223                    s += '    #interrupt-cells = <1>;\n'
1224                    s += '    clocks = <&freq>;\n'         # XCU contains a timer
1225                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1226                    s += '  };\n\n'
1227
1228                # search PIC (non replicated)
1229                if ( periph.ptype == 'PIC' ):
1230                    found_pic     = True
1231
1232                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1233                    s += '    compatible = "soclib,vci_iopic";\n'
1234                    s += '    interrupt-controller;\n'
1235                    s += '    #interrupt-cells = <1>;\n'
1236                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1237                    s += '  };\n\n'
1238
1239            # we need one interrupt controler in any cluster containing peripherals
1240            if ( (found_xcu == False) and
1241                 (found_pic == False) and
1242                 (len(cluster.periphs) > 0) ):
1243                print '[genmap error] in linux_dts()'
1244                print '    No XCU/PIC in cluster(%d,%d)' % (x,y)
1245                sys.exit(1)
1246
1247            # scan all periphs to find TTY and IOC in current cluster
1248            for periph in cluster.periphs:
1249                msb     = periph.pseg.base >> 32
1250                lsb     = periph.pseg.base & 0xFFFFFFFF
1251                size    = periph.pseg.size
1252
1253                irq_ctrl = periph.irq_ctrl
1254                if irq_ctrl != None:
1255                    irq_ctrl_name = '%s@0x%x' % (irq_ctrl.pseg.name, irq_ctrl.pseg.base)
1256
1257                # search TTY (non replicated)
1258                if periph.ptype == 'TTY':
1259                    assert irq_ctrl != None
1260
1261                    # get HWI index to XCU or PIC (only TTY0 is used by Linux)
1262                    hwi_id = 0xFFFFFFFF
1263                    for irq in irq_ctrl.irqs:
1264                        if ( (irq.isrtype == 'ISR_TTY_RX') and (irq.channel == 0) ):
1265                            hwi_id = irq.srcid
1266
1267                    if ( hwi_id == 0xFFFFFFFF ):
1268                        print '[genmap error] in linux.dts()'
1269                        print '    IRQ_TTY_RX not found'
1270                        sys.exit(1)
1271
1272                    if chosen_tty == False:
1273                        chosen_tty = True
1274                        s += '  tty:\n'
1275
1276                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1277                    s += '    compatible = "soclib,vci_multi_tty";\n'
1278                    s += '    interrupt-parent = <&{/%s}>;\n' % (irq_ctrl_name)
1279                    s += '    interrupts = <%d>;\n' % hwi_id
1280                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1281                    s += '  };\n\n'
1282
1283
1284                # search IOC (non replicated)
1285                elif ( periph.ptype == 'IOC' ):
1286                    assert irq_ctrl != None
1287
1288                    if ( periph.subtype == 'BDV' ):
1289
1290                        # get irq line index associated to bdv
1291                        hwi_id = 0xFFFFFFFF
1292                        for irq in irq_ctrl.irqs:
1293                            if ( irq.isrtype == 'ISR_BDV' ): hwi_id = irq.srcid
1294
1295                        if ( hwi_id == 0xFFFFFFFF ):
1296                            print '[genmap error] in linux.dts()'
1297                            print '    ISR_BDV not found'
1298                            sys.exit(1)
1299
1300                        s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1301                        s += '    compatible = "tsar,vci_block_device";\n'
1302                        s += '    interrupt-parent = <&{/%s}>;\n' % (irq_ctrl_name)
1303                        s += '    interrupts = <%d>;\n' % hwi_id
1304                        s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1305                        s += '  };\n\n'
1306
1307                    else:
1308                        print '[genmap warning] in linux_dts() : '
1309                        print ' %s' % (periph.subtype),
1310                        print 'peripheral not supported by LINUX'
1311
1312                # XCU or PIC have been already parsed
1313                elif ( periph.ptype == 'XCU' ) or ( periph.ptype == 'PIC' ):
1314                    pass
1315
1316                # other peripherals
1317                else:
1318                    print '[genmap warning] in linux_dts() : '
1319                    print ' %s peripheral not supported by LINUX' % (periph.ptype)
1320
1321        # clocks
1322        s += '  clocks {\n'
1323        s += '    freq: freq@50MHZ {\n'
1324        s += '      #clock-cells = <0>;\n'
1325        s += '      compatible = "fixed-clock";\n'
1326        s += '      clock-frequency = <50000000>;\n'
1327        s += '    };\n'
1328        s += '  };\n\n'
1329        s += '  cpuclk {\n'
1330        s += '    compatible = "soclib,mips32_clksrc";\n'
1331        s += '    clocks = <&freq>;\n'
1332        s += '  };\n'
1333        s += '};\n'
1334
1335        return s
1336        # end linux_dts()
1337
1338
1339    #################################################################
1340    def netbsd_dts( self ):    # compute string for netbsd.dts file
1341                               # used for netbsd configuration
1342        # header
1343        s =  '/dts-v1/;\n'
1344        s += '\n'
1345        s += '/{\n'
1346        s += '  #address-cells = <2>;\n'
1347        s += '  #size-cells    = <1>;\n'
1348
1349        # cpus (for each cluster)
1350        s += '  cpus {\n'
1351        s += '    #address-cells = <1>;\n'
1352        s += '    #size-cells    = <0>;\n'
1353
1354        for cluster in self.clusters:
1355            for proc in cluster.procs:
1356                proc_id = (((cluster.x << self.y_width) + cluster.y)
1357                              << self.p_width) + proc.lpid
1358
1359                s += '    Mips,32@0x%x {\n'                % proc_id
1360                s += '      device_type = "cpu";\n'
1361                s += '      icudev_type = "cpu:mips";\n'
1362                s += '      name        = "Mips,32";\n'
1363                s += '      reg         = <0x%x>;\n'     % proc_id
1364                s += '    };\n'
1365                s += '\n'
1366
1367        s += '  };\n'
1368
1369        # physical memory banks (for each cluster)
1370        for cluster in self.clusters:
1371            for pseg in cluster.psegs:
1372
1373                if ( pseg.segtype == 'RAM' ):
1374                    msb  = pseg.base >> 32
1375                    lsb  = pseg.base & 0xFFFFFFFF
1376                    size = pseg.size
1377
1378                    s += %s@0x%x {\n' % (pseg.name, pseg.base)
1379                    s += '    cached      = <1>;\n'
1380                    s += '    device_type = "memory";\n'
1381                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb,lsb,size)
1382                    s += '  };\n'
1383
1384        # peripherals (for each cluster)
1385        for cluster in self.clusters:
1386            x = cluster.x
1387            y = cluster.y
1388
1389            # research XCU or PIC component
1390            found_xcu = False
1391            found_pic = False
1392            for periph in cluster.periphs:
1393                if ( (periph.ptype == 'XCU') ):
1394                    found_xcu = True
1395                    xcu = periph
1396                    msb  = periph.pseg.base >> 32
1397                    lsb  = periph.pseg.base & 0xFFFFFFFF
1398                    size = periph.pseg.size
1399
1400                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1401                    s += '    device_type = "soclib:xicu:root";\n'
1402                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb,lsb,size)
1403                    s += '    input_lines = <%d>;\n'    % periph.arg0
1404                    s += '    ipis        = <%d>;\n'    % periph.arg1
1405                    s += '    timers      = <%d>;\n'    % periph.arg2
1406
1407                    output_id = 0            # output index from XCU
1408                    for lpid in xrange ( len(cluster.procs) ):        # destination processor index
1409                        for itid in xrange ( self.irq_per_proc ):     # input irq index on processor
1410                            cluster_xy = (cluster.x << self.y_width) + cluster.y
1411                            proc_id    = (cluster_xy << self.p_width) + lpid
1412                            s += '    out@%d {\n' % output_id
1413                            s += '      device_type = "soclib:xicu:filter";\n'
1414                            s += '      irq = <&{/cpus/Mips,32@0x%x} %d>;\n' % (proc_id, itid)
1415                            s += '      output_line = <%d>;\n' % output_id
1416                            s += '      parent = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1417                            s += '    };\n'
1418
1419                            output_id += 1
1420
1421                    s += '  };\n'
1422
1423                if ( periph.ptype == 'PIC' ):
1424                    found_pic = True
1425                    pic  = periph
1426                    msb  = periph.pseg.base >> 32
1427                    lsb  = periph.pseg.base & 0xFFFFFFFF
1428                    size = periph.pseg.size
1429
1430                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1431                    s += '    device_type = "soclib:pic:root";\n'
1432                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1433                    s += '    input_lines = <%d>;\n' % periph.channels
1434                    s += '  };\n'
1435
1436            # at least one interrupt controller
1437            if ( (found_xcu == False) and (found_pic == False) and (len(cluster.periphs) > 0) ):
1438                print '[genmap error] in netbsd_dts()'
1439                print '    No XCU/PIC in cluster(%d,%d)' % (x,y)
1440                sys.exit(1)
1441
1442            # get all others peripherals in cluster
1443            for periph in cluster.periphs:
1444                msb  = periph.pseg.base >> 32
1445                lsb  = periph.pseg.base & 0xFFFFFFFF
1446                size = periph.pseg.size
1447
1448                irq_ctrl = periph.irq_ctrl
1449                if irq_ctrl != None:
1450                    irq_ctrl_name = '%s@0x%x' % (irq_ctrl.pseg.name, irq_ctrl.pseg.base)
1451
1452                # XCU or PIC have been already parsed
1453                if ( periph.ptype == 'XCU' ) or ( periph.ptype == 'PIC' ):
1454                    pass
1455
1456                # research DMA component
1457                elif ( periph.ptype == 'DMA' ):
1458
1459                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1460                    s += '    device_type = "soclib:dma";\n'
1461                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1462                    s += '    channel_count = <%d>;\n' % periph.channels
1463
1464                    # multi-channels : get HWI index (to XCU) for each channel
1465                    for channel in xrange( periph.channels ):
1466                        hwi_id = 0xFFFFFFFF
1467                        for irq in xcu.irqs:
1468                            if ( (irq.isrtype == 'ISR_DMA') and
1469                                 (irq.channel == channel) ):
1470                                hwi_id = irq.srcid
1471
1472                        if ( hwi_id == 0xFFFFFFFF ):
1473                            print '[genmap error] in netbsd.dts()'
1474                            print '    ISR_DMA channel %d not found' % channel
1475                            sys.exit(1)
1476
1477                        name = '%s@0x%x' % (xcu.pseg.name, xcu.pseg.base)
1478                        s += '    irq@%d{\n' % channel
1479                        s += '      device_type = "soclib:periph:irq";\n'
1480                        s += '      output_line = <%d>;\n' % channel
1481                        s += '      irq = <&{/%s%d>;\n' % (name, hwi_id)
1482                        s += '      parent = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1483                        s += '    };\n'
1484
1485                    s += '  };\n'
1486
1487                # research MMC component
1488                elif ( periph.ptype == 'MMC' ):
1489
1490                    # get irq line index associated to MMC in XCU
1491                    irq_in = 0xFFFFFFFF
1492                    for irq in xcu.irqs:
1493                        if ( irq.isrtype == 'ISR_MMC' ): irq_in = irq.srcid
1494
1495                    if ( irq_in == 0xFFFFFFFF ):
1496                        print '[genmap error] in netbsd.dts()'
1497                        print '    ISR_MMC not found'
1498                        sys.exit(1)
1499
1500                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1501                    s += '    device_type = "soclib:mmc";\n'
1502                    s += '    irq = <&{/%s} %d>;\n' % (irq_ctrl_name, irq_in)
1503                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1504                    s += '  };\n'
1505
1506                # research FBF component
1507                elif ( periph.ptype == 'FBF' ):
1508
1509                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1510                    s += '    device_type = "soclib:framebuffer";\n'
1511                    s += '    mode        = <32>;\n'            # bits par pixel
1512                    s += '    width       = <%d>;\n'    % periph.arg0
1513                    s += '    height      = <%d>;\n'    % periph.arg1
1514                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1515                    s += '  };\n'
1516
1517                # research IOC component
1518                elif ( periph.ptype == 'IOC' ):
1519
1520                    if   ( periph.subtype == 'BDV' ):
1521
1522                        # get irq line index associated to bdv
1523                        irq_in = 0xFFFFFFFF
1524                        for irq in irq_ctrl.irqs:
1525                            if ( irq.isrtype == 'ISR_BDV' ): irq_in = irq.srcid
1526                        if ( irq_in == 0xFFFFFFFF ):
1527                            print '[genmap error] in netbsd.dts()'
1528                            print '    ISR_BDV not found'
1529                            sys.exit(1)
1530
1531                        s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1532                        s += '    device_type = "soclib:blockdevice";\n'
1533                        s += '    irq = <&{/%s} %d>;\n' % (irq_ctrl_name, irq_in)
1534                        s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1535                        s += '  };\n'
1536
1537                    elif ( periph.subtype == 'HBA' ):
1538
1539                        print '[genmap error] in netbsd_dts()'
1540                        print '    HBA peripheral not supported by NetBSD'
1541
1542                    elif ( periph.subtype == 'SDC' ):
1543
1544                        # get irq line index associated to sdc
1545                        irq_in = 0xFFFFFFFF
1546                        for irq in irq_ctrl.irqs:
1547                            if ( irq.isrtype == 'ISR_SDC' ): irq_in = irq.srcid
1548                        if ( irq_in == 0xFFFFFFFF ):
1549                            print '[genmap error] in netbsd.dts()'
1550                            print '    ISR_SDC not found'
1551                            sys.exit(1)
1552
1553                        s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1554                        s += '    device_type = "soclib:sdc";\n'
1555                        s += '    irq = <&{/%s} %d>;\n' % (irq_ctrl_name, irq_in)
1556                        s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1557                        s += '  };\n'
1558
1559                # research ROM component
1560                elif ( periph.ptype == 'ROM' ) or ( periph.ptype == 'DROM' ):
1561
1562                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1563                    s += '    device_type = "rom";\n'
1564                    s += '    cached = <1>;\n'
1565                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1566                    s += '  };\n'
1567
1568                # research SIM component
1569                elif ( periph.ptype == 'SIM' ):
1570
1571                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1572                    s += '    device_type = "soclib:simhelper";\n'
1573                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1574                    s += '  };\n'
1575
1576                # research TTY component
1577                elif ( periph.ptype == 'TTY' ):
1578
1579                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1580                    s += '    device_type = "soclib:tty";\n'
1581                    s += '    channel_count = < %d >;\n' % periph.channels
1582                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1583
1584                    # multi-channels : get HWI index (to XCU or PIC) for each channel
1585                    for channel in xrange( periph.channels ):
1586                        hwi_id = 0xFFFFFFFF
1587                        for irq in irq_ctrl.irqs:
1588                            if ( (irq.isrtype == 'ISR_TTY_RX') and (irq.channel == channel) ):
1589                                hwi_id = irq.srcid
1590                        if ( hwi_id == 0xFFFFFFFF ):
1591                            print '[genmap error] in netbsd.dts()'
1592                            print '    ISR_TTY_RX channel %d not found' % channel
1593                            sys.exit(1)
1594
1595                        name = '%s' % (irq_ctrl_name)
1596                        s += '    irq@%d{\n' % channel
1597                        s += '      device_type = "soclib:periph:irq";\n'
1598                        s += '      output_line = <%d>;\n' % channel
1599                        s += '      irq = <&{/%s%d>;\n' % (name, hwi_id)
1600                        s += '      parent = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1601                        s += '    };\n'
1602
1603                    s += '  };\n'
1604
1605                # research IOB component
1606                elif ( periph.ptype == 'IOB' ):
1607
1608                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1609                    s += '    device_type = "soclib:iob";\n'
1610                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1611                    s += '  };\n'
1612
1613                # research NIC component
1614                elif ( periph.ptype == 'NIC' ):
1615
1616                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1617                    s += '    device_type   = "soclib:nic";\n'
1618                    s += '    reg           = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1619                    s += '    channel_count = < %d >;\n' % periph.channels
1620
1621                    # multi-channels : get HWI index (to XCU or PIC) for RX & TX IRQs
1622                    # RX IRQ : (2*channel) / TX IRQs : (2*channel + 1)
1623                    for channel in xrange( periph.channels ):
1624                        hwi_id = 0xFFFFFFFF
1625                        for irq in irq_ctrl.irqs:
1626                            if ( (irq.isrtype == 'ISR_NIC_RX') and (irq.channel == channel) ):
1627                                hwi_id = irq.srcid
1628                        if ( hwi_id == 0xFFFFFFFF ):
1629                            print '[genmap error] in netbsd.dts()'
1630                            print '    ISR_NIC_RX channel %d not found' % channel
1631                            sys.exit(1)
1632
1633                        name = '%s' % (irq_ctrl_name)
1634                        s += '    irq_rx@%d{\n' % channel
1635                        s += '      device_type = "soclib:periph:irq";\n'
1636                        s += '      output_line = <%d>;\n' % (2*channel)
1637                        s += '      irq         = <&{/%s%d>;\n' % (name, hwi_id)
1638                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1639                        s += '    };\n'
1640
1641                        hwi_id = 0xFFFFFFFF
1642                        for irq in irq_ctrl.irqs:
1643                            if ( (irq.isrtype == 'ISR_NIC_TX') and (irq.channel == channel) ):
1644                                hwi_id = irq.srcid
1645                        if ( hwi_id == 0xFFFFFFFF ):
1646                            print '[genmap error] in netbsd.dts()'
1647                            print '    ISR_NIC_TX channel %d not found' % channel
1648                            sys.exit(1)
1649
1650                        name = '%s' % (irq_ctrl_name)
1651                        s += '    irq_tx@%d{\n' % channel
1652                        s += '      device_type = "soclib:periph:irq";\n'
1653                        s += '      output_line = <%d>;\n' % (2*channel + 1)
1654                        s += '      irq         = <&{/%s%d>;\n' % (name, hwi_id)
1655                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1656                        s += '    };\n'
1657
1658                    s += '  };\n'
1659
1660                # research CMA component
1661                elif ( periph.ptype == 'CMA' ):
1662
1663                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1664                    s += '    device_type   = "soclib:cma";\n'
1665                    s += '    reg           = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1666                    s += '    channel_count = < %d >;\n' % periph.channels
1667
1668                    # multi-channels : get HWI index (to XCU or PIC) for each channel
1669                    for channel in xrange( periph.channels ):
1670                        hwi_id = 0xFFFFFFFF
1671                        for irq in irq_ctrl.irqs:
1672                            if ( (irq.isrtype == 'ISR_CMA') and (irq.channel == channel) ):
1673                                hwi_id = irq.srcid
1674
1675                        if ( hwi_id == 0xFFFFFFFF ):
1676                            print '[genmap error] in netbsd.dts()'
1677                            print '    ISR_CMA channel %d not found' % channel
1678                            sys.exit(1)
1679
1680                        name = '%s' % (irq_ctrl_name)
1681                        s += '    irq@%d{\n' % channel
1682                        s += '      device_type = "soclib:periph:irq";\n'
1683                        s += '      output_line = <%d>;\n' % channel
1684                        s += '      irq = <&{/%s%d>;\n' % (name, hwi_id)
1685                        s += '      parent = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1686                        s += '    };\n'
1687
1688                    s += '  };\n'
1689
1690                else:
1691
1692                    print '[genmap error] in netbsd_dts()'
1693                    print '    %s peripheral not supported by NetBSD' % periph.ptype
1694
1695
1696        # topology
1697        s += '\n'
1698        s += '  topology {\n'
1699        s += '    #address-cells = <2>;\n'
1700        s += '    #size-cells = <0>;\n'
1701        for cluster in self.clusters:
1702            s += '    cluster@%d,%d {\n' % (cluster.x, cluster.y)
1703            s += '      reg     = <%d %d>;\n' % (cluster.x, cluster.y)
1704            s += '      devices = <\n'
1705
1706            offset = ((cluster.x << self.y_width) + cluster.y) << self.p_width
1707            for proc in cluster.procs:
1708                s += '                &{/cpus/Mips,32@0x%x}\n' % (offset + proc.lpid)
1709            for periph in cluster.periphs:
1710                s += '                &{/%s@0x%x}\n' % (periph.pseg.name, periph.pseg.base)
1711            for pseg in cluster.psegs:
1712                if ( pseg.segtype == 'RAM' ):
1713                    s += '                &{/%s@0x%x}\n' % (pseg.name, pseg.base)
1714
1715            s += '                >;\n'
1716            s += '    };\n'
1717        s += '  };\n'
1718        s += '};\n'
1719
1720        return s
1721        # end netbsd_dts()
1722
1723    ######################################################################
1724    def almos_archinfo( self ):    # compute string for arch.info file
1725                                   # used for almos configuration
1726        # header
1727        s =  '# arch.info file generated by genmap for %s\n' % self.name
1728        s += '\n'
1729        s += '[HEADER]\n'
1730        s += '        REVISION=1\n'
1731        s += '        ARCH=%s\n'            % self.name
1732        s += '        XMAX=%d\n'            % self.x_size
1733        s += '        YMAX=%d\n'            % self.y_size
1734        s += '        CPU_NR=%d\n'          % self.nprocs
1735        s += '\n'
1736
1737        # clusters
1738        cluster_id = 0
1739        for cluster in self.clusters:
1740
1741            ram = None
1742            nb_cpus = len( cluster.procs )
1743            nb_devs = len( cluster.periphs )
1744
1745            # search a RAM
1746            for pseg in cluster.psegs:
1747                if ( pseg.segtype == 'RAM' ):
1748                    ram     = pseg
1749                    nb_devs += 1
1750
1751            # search XCU to get IRQs indexes if cluster contains peripherals
1752            if ( len( cluster.periphs ) != 0 ):
1753                tty_irq_id = None
1754                bdv_irq_id = None
1755                dma_irq_id = None
1756
1757                for periph in cluster.periphs:
1758                    if ( periph.ptype == 'XCU' ):
1759                        # scan irqs
1760                        for irq in periph.irqs:
1761                            if (irq.isrtype=='ISR_TTY_RX'): tty_irq_id = irq.srcid
1762                            if (irq.isrtype=='ISR_BDV'   ): bdv_irq_id = irq.srcid
1763                            if (irq.isrtype=='ISR_DMA'   ): dma_irq_id = irq.srcid
1764
1765            # Build the cluster description
1766            s += '[CLUSTER]\n'
1767            s += '         CID=%d\n'        % cluster_id
1768            s += '         ARCH_CID=0x%x\n' % ((cluster.x<<self.y_width)+cluster.y)
1769            s += '         CPU_NR=%d\n'     % nb_cpus
1770            s += '         DEV_NR=%d\n'     % nb_devs
1771
1772
1773            # Handling RAM when cluster contain a RAM
1774            if (ram != None ):
1775                base  = ram.base
1776                size  = ram.size
1777                irqid = -1
1778                s += '         DEVID=RAM'
1779                s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % (base,size)
1780
1781            # Handling peripherals
1782            for periph in cluster.periphs:
1783                base  = periph.pseg.base
1784                size  = periph.pseg.size
1785
1786                if   ( periph.ptype == 'XCU' ):
1787
1788                    s += '         DEVID=XICU'
1789                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' %(base,size)
1790
1791                elif ( (periph.ptype == 'TTY')
1792                       and (tty_irq_id != None) ):
1793
1794                    s += '         DEVID=TTY'
1795                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' %(base,size,tty_irq_id)
1796
1797                elif ( (periph.ptype == 'DMA')
1798                       and (dma_irq_id != None) ):
1799
1800                    s += '         DEVID=DMA'
1801                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' %(base,size,dma_irq_id)
1802
1803                elif ( periph.ptype == 'FBF' ):
1804
1805                    s += '         DEVID=FB'
1806                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' %(base,size )
1807
1808                elif ( (periph.ptype == 'IOC') and (periph.subtype == 'BDV')
1809                       and (bdv_irq_id != None) ):
1810
1811                    s += '         DEVID=BLKDEV'
1812                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' %(base,size,bdv_irq_id)
1813
1814                elif ( periph.ptype == 'PIC' ):
1815
1816                    s += '         DEVID=IOPIC'
1817                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' %(base,size)
1818
1819                else:
1820                    print '# Warning from almos_archinfo() in cluster[%d,%d]' \
1821                          % (cluster.x, cluster.y)
1822                    print '# peripheral type %s/%s not supported yet\n' \
1823                          % ( periph.ptype, periph.subtype )
1824
1825            cluster_id += 1
1826
1827        return s
1828
1829    # end of almos_archinfo()
1830
1831
1832
1833
1834
1835
1836
1837
1838###################################################################################
1839class Cluster ( object ):
1840###################################################################################
1841    def __init__( self,
1842                  x,
1843                  y ):
1844
1845        self.index       = 0           # global index (set by Mapping constructor)
1846        self.x           = x           # x coordinate
1847        self.y           = y           # y coordinate
1848        self.psegs       = []          # filled by addRam() or addPeriph()
1849        self.procs       = []          # filled by addProc()
1850        self.periphs     = []          # filled by addPeriph()
1851
1852        return
1853
1854    ################
1855    def xml( self ):  # xml for a cluster
1856
1857        s = '        <cluster x="%d" y="%d" >\n' % (self.x, self.y)
1858        for pseg in self.psegs:   s += pseg.xml()
1859        for proc in self.procs:   s += proc.xml()
1860        for peri in self.periphs: s += peri.xml()
1861        s += '        </cluster>\n'
1862
1863        return s
1864
1865    #############################################
1866    def cbin( self, mapping, verbose, expected ):  # C binary structure for Cluster
1867
1868        if ( verbose ):
1869            print '*** cbin for cluster [%d,%d]' % (self.x, self.y)
1870
1871        # check index
1872        if (self.index != expected):
1873            print '[genmap error] in Cluster.cbin()'
1874            print '    cluster global index = %d / expected = %d' \
1875                       % (self.index,expected)
1876            sys.exit(1)
1877
1878        # compute global index for first pseg
1879        if ( len(self.psegs) > 0 ):
1880            pseg_id = self.psegs[0].index
1881        else:
1882            pseg_id = 0
1883
1884        # compute global index for first proc
1885        if ( len(self.procs) > 0 ):
1886            proc_id = self.procs[0].index
1887        else:
1888            proc_id = 0
1889
1890        # compute global index for first periph
1891        if ( len(self.periphs) > 0 ):
1892            periph_id = self.periphs[0].index
1893        else:
1894            periph_id = 0
1895
1896        byte_stream = bytearray()
1897        byte_stream += mapping.int2bytes(4,self.x)            # x coordinate
1898        byte_stream += mapping.int2bytes(4,self.y)            # x coordinate
1899        byte_stream += mapping.int2bytes(4,len(self.psegs))   # psegs in cluster
1900        byte_stream += mapping.int2bytes(4,pseg_id )          # global index
1901        byte_stream += mapping.int2bytes(4,len(self.procs))   # procs in cluster
1902        byte_stream += mapping.int2bytes(4,proc_id )          # global index
1903        byte_stream += mapping.int2bytes(4,len(self.periphs)) # periphs in cluster
1904        byte_stream += mapping.int2bytes(4, periph_id )       # global index
1905
1906        if ( verbose ):
1907            print 'nb_psegs   = %d' %  len( self.psegs )
1908            print 'pseg_id    = %d' %  pseg_id
1909            print 'nb_procs   = %d' %  len( self.procs )
1910            print 'proc_id    = %d' %  proc_id
1911            print 'nb_periphs = %d' %  len( self.periphs )
1912            print 'periph_id  = %d' %  periph_id
1913
1914        return byte_stream
1915
1916##################################################################################
1917class Vspace( object ):
1918##################################################################################
1919    def __init__( self,
1920                  name,
1921                  startname,
1922                  active ):
1923
1924        self.index     = 0              # global index ( set by addVspace() )
1925        self.name      = name           # vspace name
1926        self.startname = startname      # name of vseg containing the start_vector
1927        self.active    = active         # active at boot if true
1928        self.vsegs     = []
1929        self.threads   = []
1930
1931        return
1932
1933    ################
1934    def xml( self ):   # xml for one vspace
1935
1936        s =  '        <vspace name="%s" startname="%s" active="%d" >\n' \
1937                            %(self.name , self.startname , self.active)
1938        for vseg in self.vsegs: s += vseg.xml()
1939        for thread in self.threads: s += thread.xml()
1940        s += '        </vspace>\n'
1941
1942        return s
1943
1944    #############################################
1945    def cbin( self, mapping, verbose, expected ):   # C binary for Vspace
1946
1947        if ( verbose ):
1948            print '*** cbin for vspace %s' % (self.name)
1949
1950        # check index
1951        if (self.index != expected):
1952            print '[genmap error] in Vspace.cbin()'
1953            print '    vspace global index = %d / expected = %d' \
1954                        %(self.index,expected)
1955            sys.exit(1)
1956
1957        # compute global index for vseg containing start_vector
1958        vseg_start_id = 0xFFFFFFFF
1959        for vseg in self.vsegs:
1960            if ( vseg.name == self.startname ): vseg_start_id = vseg.index
1961
1962        if ( vseg_start_id == 0xFFFFFFFF ):
1963            print '[genmap error] in Vspace.cbin()'
1964            print '    startname %s not found for vspace %s' \
1965                        %(self.startname,self.name)
1966            sys.exit(1)
1967
1968        # compute first vseg and first thread global index
1969        first_vseg_id = self.vsegs[0].index
1970        first_thread_id = self.threads[0].index
1971
1972        # compute number of threads and number of vsegs
1973        nb_vsegs = len( self.vsegs )
1974        nb_threads = len( self.threads )
1975
1976        byte_stream = bytearray()
1977        byte_stream += mapping.str2bytes(32,self.name)         # vspace name
1978        byte_stream += mapping.int2bytes(4, vseg_start_id)     # vseg start_vector
1979        byte_stream += mapping.int2bytes(4, nb_vsegs)          # number of vsegs
1980        byte_stream += mapping.int2bytes(4, nb_threads)        # number of threads
1981        byte_stream += mapping.int2bytes(4, first_vseg_id)     # global index
1982        byte_stream += mapping.int2bytes(4, first_thread_id)     # global index
1983        byte_stream += mapping.int2bytes(4, self.active)       # always active if non zero
1984
1985        if ( verbose ):
1986            print 'start_id   = %d' %  vseg_start_id
1987            print 'nb_vsegs   = %d' %  nb_vsegs
1988            print 'nb_threads = %d' %  nb_threads
1989            print 'vseg_id    = %d' %  first_vseg_id
1990            print 'thread_id  = %d' %  first_thread_id
1991            print 'active     = %d' %  self.active
1992
1993        return byte_stream
1994
1995##################################################################################
1996class Thread( object ):
1997##################################################################################
1998    def __init__( self,
1999                  name,
2000                  is_main,
2001                  x,
2002                  y,
2003                  p,
2004                  stackname,
2005                  heapname,
2006                  startid ):
2007
2008        self.index     = 0             # global index value set by addThread()
2009        self.name      = name          # thread name
2010        self.is_main   = is_main       # Boolean (one main per vspace)
2011        self.x         = x             # cluster x coordinate
2012        self.y         = y             # cluster y coordinate
2013        self.p         = p             # processor local index
2014        self.stackname = stackname     # name of vseg containing the stack
2015        self.heapname  = heapname      # name of vseg containing the heap
2016        self.startid   = startid       # index in start_vector
2017        return
2018
2019    ########################################
2020    def xml( self ):    # xml for one thread
2021
2022        s =  '            <thread name="%s"' % self.name
2023        s += ' is_main="%d"'               % self.is_main
2024        s += ' x="%d"'                     % self.x
2025        s += ' y="%d"'                     % self.y
2026        s += ' p="%d"'                     % self.p
2027        s += '\n                 '
2028        s += ' stackname="%s"'             % self.stackname
2029        s += ' heapname="%s"'              % self.heapname
2030        s += ' startid="%d"'               % self.startid
2031        s += ' />\n'
2032
2033        return s
2034
2035    ############################################################################
2036    def cbin( self, mapping, verbose, expected, vspace ):  # C binary for Thread
2037
2038        if ( verbose ):
2039            print '*** cbin for thread %s in vspace %s' \
2040                     % (self.name, vspace.name)
2041
2042        # check index
2043        if (self.index != expected):
2044            print '[genmap error] in Thread.cbin()'
2045            print '    thread global index = %d / expected = %d' \
2046                        %(self.index,expected)
2047            sys.exit(1)
2048
2049        # compute cluster global index
2050        cluster_id = (self.x * mapping.y_size) + self.y
2051
2052        # compute vseg index for stack
2053        vseg_stack_id = 0xFFFFFFFF
2054        for vseg in vspace.vsegs:
2055            if ( vseg.name == self.stackname ): vseg_stack_id = vseg.index
2056
2057        if ( vseg_stack_id == 0xFFFFFFFF ):
2058            print '[genmap error] in Thread.cbin()'
2059            print '    stackname %s not found for thread %s in vspace %s' \
2060                  % ( self.stackname, self.name, vspace.name )
2061            sys.exit(1)
2062
2063        # compute vseg index for heap
2064        if ( self.heapname == '' ):
2065            vseg_heap_id = 0
2066        else:
2067            vseg_heap_id = 0xFFFFFFFF
2068            for vseg in vspace.vsegs:
2069                if ( vseg.name == self.heapname ): vseg_heap_id = vseg.index
2070
2071            if ( vseg_heap_id == 0xFFFFFFFF ):
2072                print '[genmap error] in Thread.cbin()'
2073                print '    heapname %s not found for thread %s in vspace %s' \
2074                      % ( self.heapname, self.name, vspace.name )
2075                sys.exit(1)
2076
2077        byte_stream = bytearray()
2078        byte_stream += mapping.str2bytes(32,self.name)     # thread name in vspace
2079        byte_stream += mapping.int2bytes(4, cluster_id)    # cluster global index
2080        byte_stream += mapping.int2bytes(4, self.p)        # processor local index
2081        byte_stream += mapping.int2bytes(4, self.is_main)  # main if non zero
2082        byte_stream += mapping.int2bytes(4, vseg_stack_id) # stack vseg local index
2083        byte_stream += mapping.int2bytes(4, vseg_heap_id)  # heap vseg local index
2084        byte_stream += mapping.int2bytes(4, self.startid)  # index in start vector
2085        byte_stream += mapping.int2bytes(4 ,0)             # ltid (dynamically computed)
2086
2087        if ( verbose ):
2088            print 'clusterid  = %d' %  cluster_id
2089            print 'lpid       = %d' %  self.p
2090            print 'is_main    = %d' %  self.is_main
2091            print 'stackid    = %d' %  vseg_stack_id
2092            print 'heapid     = %d' %  vseg_heap_id
2093            print 'startid    = %d' %  self.startid
2094
2095        return byte_stream
2096
2097##################################################################################
2098class Vseg( object ):
2099##################################################################################
2100    def __init__( self,
2101                  name,
2102                  vbase,
2103                  length,
2104                  mode,
2105                  vtype,
2106                  x,
2107                  y,
2108                  pseg,
2109                  identity = False,
2110                  local    = False,
2111                  big      = False,
2112                  binpath  = '' ):
2113
2114        assert (vbase & 0xFFFFFFFF) == vbase
2115
2116        assert (length & 0xFFFFFFFF) == length
2117
2118        assert mode in VSEGMODES
2119
2120        assert vtype in VSEGTYPES
2121
2122        assert (vtype != 'ELF') or (binpath != '')
2123
2124        self.index    = 0                   # global index ( set by addVseg() )
2125        self.name     = name                # vseg name (unique in vspace)
2126        self.vbase    = vbase               # virtual base address in vspace
2127        self.length   = length              # vseg length (bytes)
2128        self.vtype    = vtype               # vseg type (defined in VSEGTYPES)
2129        self.mode     = mode                # CXWU access rights
2130        self.x        = x                   # x coordinate of destination cluster
2131        self.y        = y                   # y coordinate of destination cluster
2132        self.psegname = pseg                # name of pseg in destination cluster
2133        self.identity = identity            # identity mapping required
2134        self.local    = local               # only mapped in local PTAB when true
2135        self.big      = big                 # to be mapped in a big physical page
2136        self.binpath  = binpath             # pathname for binary file (ELF or BLOB)
2137
2138        return
2139
2140    ##################################
2141    def xml( self ):  # xml for a vseg
2142
2143        s =  '            <vseg name="%s"' %(self.name)
2144        s += ' vbase="0x%x"'               %(self.vbase)
2145        s += ' length="0x%x"'              %(self.length)
2146        s += ' type="%s"'                  %(self.vtype)
2147        s += ' mode="%s"'                  %(self.mode)
2148        s += '\n                 '
2149        s += ' x="%d"'                     %(self.x)
2150        s += ' y="%d"'                     %(self.y)
2151        s += ' psegname="%s"'              %(self.psegname)
2152        if ( self.identity ):       s += ' ident="1"'
2153        if ( self.local ):          s += ' local="1"'
2154        if ( self.big ):            s += ' big="1"'
2155        if ( self.binpath != '' ):  s += ' binpath="%s"' %(self.binpath)
2156        s += ' />\n'
2157
2158        return s
2159
2160    #####################################################################
2161    def cbin( self, mapping, verbose, expected ):    # C binary for Vseg
2162
2163        if ( verbose ):
2164            print '*** cbin for vseg[%d] %s' % (self.index, self.name)
2165
2166        # check index
2167        if (self.index != expected):
2168            print '[genmap error] in Vseg.cbin()'
2169            print '    vseg global index = %d / expected = %d' \
2170                  % (self.index, expected )
2171            sys.exit(1)
2172
2173        # compute pseg_id
2174        pseg_id = 0xFFFFFFFF
2175        cluster_id = (self.x * mapping.y_size) + self.y
2176        cluster = mapping.clusters[cluster_id]
2177        for pseg in cluster.psegs:
2178            if (self.psegname == pseg.name):
2179                pseg_id = pseg.index
2180        if (pseg_id == 0xFFFFFFFF):
2181            print '[genmap error] in Vseg.cbin() : '
2182            print '    psegname %s not found for vseg %s in cluster %d' \
2183                  % ( self.psegname, self.name, cluster_id )
2184            sys.exit(1)
2185
2186        # compute numerical value for mode
2187        mode_id = 0xFFFFFFFF
2188        for x in xrange( len(VSEGMODES) ):
2189            if ( self.mode == VSEGMODES[x] ):
2190                mode_id = x
2191        if ( mode_id == 0xFFFFFFFF ):
2192            print '[genmap error] in Vseg.cbin() : '
2193            print '    undefined vseg mode %s' % self.mode
2194            sys.exit(1)
2195
2196        # compute numerical value for vtype
2197        vtype_id = 0xFFFFFFFF
2198        for x in xrange( len(VSEGTYPES) ):
2199            if ( self.vtype == VSEGTYPES[x] ):
2200                vtype_id = x
2201        if ( vtype_id == 0xFFFFFFFF ):
2202            print '[genmap error] in Vseg.cbin()'
2203            print '    undefined vseg type %s' % self.vtype
2204            sys.exit(1)
2205
2206        byte_stream = bytearray()
2207        byte_stream += mapping.str2bytes(32,self.name )     # vseg name
2208        byte_stream += mapping.str2bytes(64,self.binpath )  # binpath
2209        byte_stream += mapping.int2bytes(4, self.vbase )    # virtual base address
2210        byte_stream += mapping.int2bytes(8, 0 )             # physical base address
2211        byte_stream += mapping.int2bytes(4, self.length )   # vseg size (bytes)
2212        byte_stream += mapping.int2bytes(4, pseg_id )       # pseg global index
2213        byte_stream += mapping.int2bytes(4, mode_id )       # CXWU flags
2214        byte_stream += mapping.int2bytes(4, vtype_id )      # vseg type
2215        byte_stream += mapping.int2bytes(1, 0 )             # mapped when non zero
2216        byte_stream += mapping.int2bytes(1, self.identity ) # identity mapping
2217        byte_stream += mapping.int2bytes(1, self.local )    # only in local PTAB
2218        byte_stream += mapping.int2bytes(1,  self.big )     # to be mapped in BPP
2219
2220        if ( verbose ):
2221            print 'binpath    = %s' %  self.binpath
2222            print 'vbase      = %x' %  self.vbase
2223            print 'pbase      = 0'
2224            print 'length     = %x' %  self.length
2225            print 'pseg_id    = %d' %  pseg_id
2226            print 'mode       = %d' %  mode_id
2227            print 'type       = %d' %  vtype_id
2228            print 'mapped     = 0'
2229            print 'ident      = %d' %  self.identity
2230            print 'local      = %d' %  self.local
2231            print 'big        = %d' %  self.big
2232
2233        return byte_stream
2234
2235##################################################################################
2236class Processor ( object ):
2237##################################################################################
2238    def __init__( self,
2239                  x,
2240                  y,
2241                  lpid ):
2242
2243        self.index    = 0      # global index ( set by addProc() )
2244        self.x        = x      # x cluster coordinate
2245        self.y        = y      # y cluster coordinate
2246        self.lpid     = lpid   # processor local index
2247
2248        return
2249
2250    ########################################
2251    def xml( self ):   # xml for a processor
2252        return '            <proc index="%d" />\n' % (self.lpid)
2253
2254    ####################################################################
2255    def cbin( self, mapping, verbose, expected ):    # C binary for Proc
2256
2257        if ( verbose ):
2258            print '*** cbin for proc %d in cluster (%d,%d)' \
2259                  % (self.lpid, self.x, self.y)
2260
2261        # check index
2262        if (self.index != expected):
2263            print '[genmap error] in Proc.cbin()'
2264            print '    proc global index = %d / expected = %d' \
2265                       % (self.index,expected)
2266            sys.exit(1)
2267
2268        byte_stream = bytearray()
2269        byte_stream += mapping.int2bytes( 4 , self.lpid )       # local index
2270
2271        return byte_stream
2272
2273##################################################################################
2274class Pseg ( object ):
2275##################################################################################
2276    def __init__( self,
2277                  name,
2278                  base,
2279                  size,
2280                  x,
2281                  y,
2282                  segtype ):
2283
2284        assert( segtype in PSEGTYPES )
2285
2286        self.index    = 0       # global index ( set by addPseg() )
2287        self.name     = name    # pseg name (unique in cluster)
2288        self.base     = base    # physical base address
2289        self.size     = size    # segment size (bytes)
2290        self.x        = x       # cluster x coordinate
2291        self.y        = y       # cluster y coordinate
2292        self.segtype  = segtype # RAM / PERI (defined in mapping_info.h)
2293
2294        return
2295
2296    ###################################
2297    def xml( self ):   # xml for a pseg
2298
2299        s = '            <pseg name="%s" type="%s" base="0x%x" length="0x%x" />\n' \
2300                         % (self.name, self.segtype, self.base, self.size)
2301        return s
2302
2303    ###########################################################################
2304    def cbin( self, mapping, verbose, expected, cluster ):  # C binary for Pseg
2305
2306        if ( verbose ):
2307            print '*** cbin for pseg[%d] %s in cluster[%d,%d]' \
2308                  % (self.index, self.name, cluster.x, cluster.y)
2309
2310        # check index
2311        if (self.index != expected):
2312            print '[genmap error] in Pseg.cbin()'
2313            print '    pseg global index = %d / expected = %d' \
2314                       % (self.index,expected)
2315            sys.exit(1)
2316
2317        # compute numerical value for segtype
2318        segtype_int = 0xFFFFFFFF
2319        for x in xrange( len(PSEGTYPES) ):
2320            if ( self.segtype == PSEGTYPES[x] ): segtype_int = x
2321
2322        if ( segtype_int == 0xFFFFFFFF ):
2323            print '[genmap error] in Pseg.cbin()'
2324            print '    undefined segment type %s' % self.segtype
2325            sys.exit(1)
2326
2327        byte_stream = bytearray()
2328        byte_stream += mapping.str2bytes(32,self.name)     # pseg name
2329        byte_stream += mapping.int2bytes(8 ,self.base)     # physical base address
2330        byte_stream += mapping.int2bytes(8 ,self.size)     # segment length
2331        byte_stream += mapping.int2bytes(4 ,segtype_int)   # segment type
2332        byte_stream += mapping.int2bytes(4 ,cluster.index) # cluster global index
2333        byte_stream += mapping.int2bytes(4 ,0)             # linked list of vsegs
2334
2335        if ( verbose ):
2336            print 'pbase      = %x' %  self.base
2337            print 'size       = %x' %  self.size
2338            print 'type       = %s' %  self.segtype
2339
2340        return byte_stream
2341
2342##################################################################################
2343class Periph ( object ):
2344##################################################################################
2345    def __init__( self,
2346                  pseg,               # associated pseg
2347                  ptype,              # peripheral type
2348                  subtype  = 'NONE',  # peripheral subtype
2349                  channels = 1,       # for multi-channels peripherals
2350                  arg0     = 0,       # optional (semantic depends on ptype)
2351                  arg1     = 0,       # optional (semantic depends on ptype)
2352                  arg2     = 0,       # optional (semantic depends on ptype)
2353                  arg3     = 0 ):     # optional (semantic depends on ptype)
2354
2355        self.index    = 0            # global index ( set by addPeriph() )
2356        self.channels = channels
2357        self.ptype    = ptype
2358        self.subtype  = subtype
2359        self.arg0     = arg0
2360        self.arg1     = arg1
2361        self.arg2     = arg2
2362        self.arg3     = arg3
2363        self.pseg     = pseg
2364        self.irqs     = []
2365        self.irq_ctrl = None         # interrupt controller peripheral
2366        return
2367
2368    ######################################
2369    def xml( self ):    # xml for a periph
2370
2371        s =  '            <periph type="%s"' % self.ptype
2372        s += ' subtype="%s"'                 % self.subtype
2373        s += ' psegname="%s"'                % self.pseg.name
2374        s += ' channels="%d"'                % self.channels
2375        s += ' arg0="%d"'                    % self.arg0
2376        s += ' arg1="%d"'                    % self.arg1
2377        s += ' arg2="%d"'                    % self.arg2
2378        s += ' arg3="%d"'                    % self.arg3
2379        if ( (self.ptype == 'PIC') or (self.ptype == 'XCU') ):
2380            s += ' >\n'
2381            for irq in self.irqs: s += irq.xml()
2382            s += '            </periph>\n'
2383        else:
2384            s += ' />\n'
2385        return s
2386
2387    ######################################################################
2388    def cbin( self, mapping, verbose, expected ):    # C binary for Periph
2389
2390        if ( verbose ):
2391            print '*** cbin for periph %s in cluster [%d,%d]' \
2392                  % (self.ptype, self.pseg.x, self.pseg.y)
2393
2394        # check index
2395        if (self.index != expected):
2396            print '[genmap error] in Periph.cbin()'
2397            print '    periph global index = %d / expected = %d' \
2398                       % (self.index,expected)
2399            sys.exit(1)
2400
2401        # compute pseg global index
2402        pseg_id = self.pseg.index
2403
2404        # compute first irq global index
2405        if ( len(self.irqs) > 0 ):
2406            irq_id = self.irqs[0].index
2407        else:
2408            irq_id = 0
2409
2410        # compute numerical value for ptype
2411        ptype_id = 0xFFFFFFFF
2412        for x in xrange( len(PERIPHTYPES) ):
2413            if ( self.ptype == PERIPHTYPES[x] ):  ptype_id = x
2414
2415        if ( ptype_id == 0xFFFFFFFF ):
2416            print '[genmap error] in Periph.cbin()'
2417            print '    undefined peripheral type %s' % self.ptype
2418            sys.exit(1)
2419
2420        # compute numerical value for subtype
2421        subtype_id = 0xFFFFFFFF
2422        if (self.ptype == 'IOC'):
2423            for x in xrange( len(IOCSUBTYPES) ):
2424                if ( self.subtype == IOCSUBTYPES[x] ):  subtype_id = x
2425        if (self.ptype == 'MWR'):
2426            for x in xrange( len(MWRSUBTYPES) ):
2427                if ( self.subtype == MWRSUBTYPES[x] ):  subtype_id = x
2428       
2429        byte_stream = bytearray()
2430        byte_stream += mapping.int2bytes(4,ptype_id)       # peripheral type
2431        byte_stream += mapping.int2bytes(4,subtype_id)     # peripheral subtype
2432        byte_stream += mapping.int2bytes(4,pseg_id)        # pseg global index
2433        byte_stream += mapping.int2bytes(4,self.channels)  # number of channels
2434        byte_stream += mapping.int2bytes(4,self.arg0)      # optionnal arg0
2435        byte_stream += mapping.int2bytes(4,self.arg1)      # optionnal arg1
2436        byte_stream += mapping.int2bytes(4,self.arg2)      # optionnal arg2
2437        byte_stream += mapping.int2bytes(4,self.arg3)      # optionnal arg3
2438        byte_stream += mapping.int2bytes(4,len(self.irqs)) # number of input irqs
2439        byte_stream += mapping.int2bytes( 4 , irq_id )     # global index
2440
2441        if ( verbose ):
2442            print 'ptype      = %d' %  ptype_id
2443            print 'subtype    = %d' %  subtype_id
2444            print 'pseg_id    = %d' %  pseg_id
2445            print 'nb_irqs    = %d' %  len( self.irqs )
2446            print 'irq_id     = %d' %  irq_id
2447        return byte_stream
2448
2449##################################################################################
2450class Irq ( object ):
2451##################################################################################
2452    def __init__( self,
2453                  irqtype,         # input IRQ type : HWI / WTI / PTI (for XCU only)
2454                  srcid,           # input IRQ index (for XCU or PIC)
2455                  isrtype,         # Type of ISR to be executed
2456                  channel = 0 ):   # channel index for multi-channel ISR
2457
2458        assert irqtype in IRQTYPES
2459        assert isrtype in ISRTYPES
2460        assert srcid < 32
2461
2462        self.index   = 0        # global index ( set by addIrq() )
2463        self.irqtype = irqtype  # IRQ type
2464        self.srcid   = srcid    # source IRQ index
2465        self.isrtype = isrtype  # ISR type
2466        self.channel = channel  # channel index (for multi-channels ISR)
2467        return
2468
2469    ################################
2470    def xml( self ):   # xml for Irq
2471
2472        s = '                <irq srctype="%s" srcid="%d" isr="%s" channel="%d" />\n' \
2473                % ( self.irqtype, self.srcid, self.isrtype, self.channel )
2474        return s
2475
2476    ####################################################################
2477    def cbin( self, mapping, verbose, expected ):     # C binary for Irq
2478
2479        if ( verbose ):
2480            print '*** cbin for irq[%d]' % (self.index)
2481
2482        # check index
2483        if (self.index != expected):
2484            print '[genmap error] in Irq.cbin()'
2485            print '    irq global index = %d / expected = %d' \
2486                       % (self.index,expected)
2487            sys.exit(1)
2488
2489        # compute numerical value for irqtype
2490        irqtype_id = 0xFFFFFFFF
2491        for x in xrange( len(IRQTYPES) ):
2492            if ( self.irqtype == IRQTYPES[x] ): irqtype_id = x
2493
2494        if ( irqtype_id == 0xFFFFFFFF ):
2495            print '[genmap error] in Irq.cbin()'
2496            print '    undefined irqtype %s' % self.irqtype
2497            sys.exit(1)
2498
2499        # compute numerical value for isrtype
2500        isrtype_id = 0xFFFFFFFF
2501        for x in xrange( len(ISRTYPES) ):
2502            if ( self.isrtype == ISRTYPES[x] ): isrtype_id = x
2503
2504        if ( isrtype_id == 0xFFFFFFFF ):
2505            print '[genmap error] in Irq.cbin()' 
2506            print '    undefined isrtype %s' % self.isrtype
2507            sys.exit(1)
2508
2509        byte_stream = bytearray()
2510        byte_stream += mapping.int2bytes( 4,  irqtype_id )
2511        byte_stream += mapping.int2bytes( 4,  self.srcid )
2512        byte_stream += mapping.int2bytes( 4,  isrtype_id )
2513        byte_stream += mapping.int2bytes( 4,  self.channel )
2514        byte_stream += mapping.int2bytes( 4,  0 )
2515        byte_stream += mapping.int2bytes( 4,  0 )
2516
2517        if ( verbose ):
2518            print 'irqtype    = %s' %  self.irqtype
2519            print 'srcid      = %d' %  self.srcid
2520            print 'isrtype    = %s' %  self.isrtype
2521            print 'channel    = %d' %  self.channel
2522
2523        return byte_stream
2524
2525# Local Variables:
2526# tab-width: 4;
2527# c-basic-offset: 4;
2528# c-file-offsets:((innamespace . 0)(inline-open . 0));
2529# indent-tabs-mode: nil;
2530# End:
2531#
2532# vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
2533
Note: See TracBrowser for help on using the repository browser.