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

Last change on this file since 563 was 562, checked in by cfuguet, 9 years ago

improve the platform's interrupt infrastructure description

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