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

Last change on this file since 495 was 492, checked in by cfuguet, 10 years ago

genmap: declare RAMs in the topology declaration of the netbsd dts

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