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

Last change on this file since 642 was 642, checked in by alain, 9 years ago

Introduce the "active" field in vspace.
When this field is set the application is directly started by the kernel_init.

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