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

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

Introduce the new MMAP type for vseg.

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