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

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

Introducing support for "VOBJ_TYPE_HEAP" in the mapping.py file.

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