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

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

Cosmetic

  • Property svn:executable set to *
File size: 110.0 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                  'DROM',
68                 ]
69
70PERIPHSUBTYPES = [
71                  'BDV',
72                  'HBA',
73                  'SPI',
74                  'NONE',
75                 ]
76
77IRQTYPES =       [
78                  'HWI',
79                  'WTI',
80                  'PTI',
81                 ]
82
83ISRTYPES =       [
84                  'ISR_DEFAULT',
85                  'ISR_TICK',
86                  'ISR_TTY_RX',
87                  'ISR_TTY_TX',
88                  'ISR_BDV',
89                  'ISR_TIMER',
90                  'ISR_WAKUP',
91                  'ISR_NIC_RX',
92                  'ISR_NIC_TX',
93                  'ISR_CMA',
94                  'ISR_MMC',
95                  'ISR_DMA',
96                  'ISR_SPI',
97                 ]
98
99VOBJTYPES =      [
100                  'ELF',
101                  'BLOB',
102                  'PTAB',
103                  'PERI',
104                  'MWMR',
105                  'LOCK',
106                  'BUFFER',
107                  'BARRIER',
108                  'CONST',
109                  'MEMSPACE',
110                  'SCHED',
111                  'HEAP',
112                 ]
113
114VSEGMODES =      [
115                  '____',
116                  '___U',
117                  '__W_',
118                  '__WU',
119                  '_X__',
120                  '_X_U',
121                  '_XW_',
122                  '_XWU',
123                  'C___',
124                  'C__U',
125                  'C_W_',
126                  'C_WU',
127                  'CX__',
128                  'CX_U',
129                  'CXW_',
130                  'CXWU',
131                 ]
132
133PSEGTYPES =      [
134                  'RAM',
135                  'ROM',        # deprecated => use PERI
136                  'PERI',
137                 ]
138
139CP_PORT_DIRS =   [
140                  'TO_COPROC',
141                  'FROM_COPROC',
142                 ]
143
144##########################################################################################
145class Mapping( object ):
146##########################################################################################
147    def __init__( self,
148                  name,                            # mapping name
149                  x_size,                          # number of clusters in a row
150                  y_size,                          # number of clusters in a column
151                  nprocs,                          # max number of processors per cluster
152                  x_width        = X_WIDTH,        # number of bits encoding x coordinate
153                  y_width        = Y_WIDTH,        # number of bits encoding y coordinate
154                  p_width        = P_WIDTH,        # number of bits encoding local proc_id
155                  paddr_width    = PADDR_WIDTH,    # number of bits for physical address
156                  coherence      = 1,              # hardware cache coherence when non-zero
157                  irq_per_proc   = 1,              # number or IRQs from XCU to processor
158                  use_ramdisk    = False,          # use ramdisk when true
159                  x_io           = 0,              # cluster_io x coordinate
160                  y_io           = 0,              # cluster_io y coordinate
161                  peri_increment = PERI_INCREMENT, # address increment for globals
162                  reset_address  = RESET_ADDRESS,  # Processor wired boot_address
163                  ram_base       = 0,              # RAM physical base in cluster[0,0]
164                  ram_size       = 0 ):            # RAM size in each cluster (bytes)
165
166        assert ( x_size <= (1<<X_WIDTH) )
167        assert ( y_size <= (1<<Y_WIDTH) )
168        assert ( nprocs <= (1<<P_WIDTH) )
169
170        self.signature      = MAPPING_SIGNATURE
171        self.name           = name
172        self.name           = name
173        self.paddr_width    = paddr_width
174        self.coherence      = coherence
175        self.x_size         = x_size
176        self.y_size         = y_size
177        self.nprocs         = nprocs
178        self.x_width        = x_width
179        self.y_width        = y_width
180        self.p_width        = p_width
181        self.irq_per_proc   = irq_per_proc
182        self.use_ramdisk    = use_ramdisk
183        self.x_io           = x_io
184        self.y_io           = y_io
185        self.peri_increment = peri_increment
186        self.reset_address  = reset_address
187        self.ram_base       = ram_base
188        self.ram_size       = ram_size
189
190        self.total_vspaces  = 0
191        self.total_globals  = 0
192        self.total_psegs    = 0
193        self.total_vsegs    = 0
194        self.total_vobjs    = 0
195        self.total_tasks    = 0
196        self.total_procs    = 0
197        self.total_irqs     = 0
198        self.total_coprocs  = 0
199        self.total_cpports  = 0
200        self.total_periphs  = 0
201
202        self.clusters       = []
203        self.globs          = []
204        self.vspaces        = []
205
206        for x in xrange( self.x_size ):
207            for y in xrange( self.y_size ):
208                cluster = Cluster( x , y )
209                cluster.index = (x * self.y_size) + y
210                self.clusters.append( cluster )
211
212        return
213
214    ##########################    add a ram pseg in a cluster
215    def addRam( self,
216                name,                  # pseg name
217                base,                  # pseg base address
218                size ):                # pseg length (bytes)
219
220        # computes cluster index and coordinates from the base address
221        paddr_lsb_width = self.paddr_width - self.x_width - self.y_width
222        cluster_xy = base >> paddr_lsb_width
223        x          = cluster_xy >> (self.y_width);
224        y          = cluster_xy & ((1 << self.y_width) - 1)
225        cluster_id = (x * self.y_size) + y
226
227        assert (base & VPN_ANTI_MASK) == 0
228
229        assert (x < self.x_size) and (y < self.y_size)
230
231        assert ( (base & ((1<<paddr_lsb_width)-1)) == self.ram_base )
232
233        assert ( size == self.ram_size )
234
235        # add one pseg in the mapping
236        pseg = Pseg( name, base, size, x, y, 'RAM' )
237        self.clusters[cluster_id].psegs.append( pseg )
238        pseg.index = self.total_psegs
239        self.total_psegs += 1
240
241        return pseg
242
243    ##############################   add a peripheral and the associated pseg in a cluster
244    def addPeriph( self,
245                   name,               # associated pseg name
246                   base,               # associated pseg base address
247                   size,               # associated pseg length (bytes)
248                   ptype,              # peripheral type
249                   subtype  = 'NONE',  # peripheral subtype
250                   channels = 1,       # number of channels
251                   arg      = 0 ):     # optional argument (semantic depends on ptype)
252
253        # computes cluster index and coordinates from the base address
254        cluster_xy = base >> (self.paddr_width - self.x_width - self.y_width)
255        x          = cluster_xy >> (self.y_width);
256        y          = cluster_xy & ((1 << self.y_width) - 1)
257        cluster_id = (x * self.y_size) + y
258
259        assert (x < self.x_size) and (y < self.y_size)
260
261        assert (base & VPN_ANTI_MASK) == 0
262
263        assert ptype in PERIPHTYPES
264
265        assert subtype in PERIPHSUBTYPES
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        nb_drom       = 0
907        drom_channels = 0
908        seg_drom_base = 0xFFFFFFFF
909        seg_drom_size = 0
910
911        use_bdv = False
912        use_spi = False
913        use_hba = False
914
915        # get peripherals attributes
916        for cluster in self.clusters:
917            for periph in cluster.periphs:
918                if   ( periph.ptype == 'CMA' ):
919                    seg_cma_base = periph.pseg.base & 0xFFFFFFFF
920                    seg_cma_size = periph.pseg.size
921                    cma_channels = periph.channels
922                    nb_cma +=1
923
924                elif ( periph.ptype == 'DMA' ):
925                    seg_dma_base = periph.pseg.base & 0xFFFFFFFF
926                    seg_dma_size = periph.pseg.size
927                    dma_channels = periph.channels
928                    nb_dma +=1
929
930                elif ( periph.ptype == 'FBF' ):
931                    seg_fbf_base = periph.pseg.base & 0xFFFFFFFF
932                    seg_fbf_size = periph.pseg.size
933                    fbf_channels = periph.channels
934                    fbf_arg      = periph.arg
935                    nb_fbf +=1
936
937                elif ( periph.ptype == 'IOB' ):
938                    seg_iob_base = periph.pseg.base & 0xFFFFFFFF
939                    seg_iob_size = periph.pseg.size
940                    iob_channels = periph.channels
941                    nb_iob +=1
942
943                elif ( periph.ptype == 'IOC' ):
944                    seg_ioc_base = periph.pseg.base & 0xFFFFFFFF
945                    seg_ioc_size = periph.pseg.size
946                    ioc_channels = periph.channels
947                    nb_ioc += 1
948
949                    if self.use_ramdisk: continue
950
951                    if   ( periph.subtype == 'BDV' ): use_bdv = True
952                    elif ( periph.subtype == 'HBA' ): use_hba = True
953                    elif ( periph.subtype == 'SPI' ): use_spi = True
954
955                elif ( periph.ptype == 'MMC' ):
956                    seg_mmc_base = periph.pseg.base & 0xFFFFFFFF
957                    seg_mmc_size = periph.pseg.size
958                    mmc_channels = periph.channels
959                    nb_mmc +=1
960
961                elif ( periph.ptype == 'MWR' ):
962                    seg_mwr_base = periph.pseg.base & 0xFFFFFFFF
963                    seg_wmr_size = periph.pseg.size
964                    mwr_channels = periph.channels
965                    nb_mwr +=1
966
967                elif ( periph.ptype == 'ROM' ):
968                    seg_rom_base = periph.pseg.base & 0xFFFFFFFF
969                    seg_rom_size = periph.pseg.size
970                    rom_channels = periph.channels
971                    nb_rom +=1
972
973                elif ( periph.ptype == 'DROM' ):
974                    seg_drom_base = periph.pseg.base & 0xFFFFFFFF
975                    seg_drom_size = periph.pseg.size
976                    drom_channels = periph.channels
977                    nb_drom +=1
978
979                elif ( periph.ptype == 'SIM' ):
980                    seg_sim_base = periph.pseg.base & 0xFFFFFFFF
981                    seg_sim_size = periph.pseg.size
982                    sim_channels = periph.channels
983                    nb_sim +=1
984
985                elif ( periph.ptype == 'NIC' ):
986                    seg_nic_base = periph.pseg.base & 0xFFFFFFFF
987                    seg_nic_size = periph.pseg.size
988                    nic_channels = periph.channels
989                    nb_nic +=1
990
991                elif ( periph.ptype == 'PIC' ):
992                    seg_pic_base = periph.pseg.base & 0xFFFFFFFF
993                    seg_pic_size = periph.pseg.size
994                    pic_channels = periph.channels
995                    nb_pic +=1
996
997                elif ( periph.ptype == 'TIM' ):
998                    seg_tim_base = periph.pseg.base & 0xFFFFFFFF
999                    seg_tim_size = periph.pseg.size
1000                    tim_channels = periph.channels
1001                    nb_tim +=1
1002
1003                elif ( periph.ptype == 'TTY' ):
1004                    seg_tty_base = periph.pseg.base & 0xFFFFFFFF
1005                    seg_tty_size = periph.pseg.size
1006                    tty_channels = periph.channels
1007                    nb_tty +=1
1008
1009                elif ( periph.ptype == 'XCU' ):
1010                    seg_xcu_base = periph.pseg.base & 0xFFFFFFFF
1011                    seg_xcu_size = periph.pseg.size
1012                    xcu_channels = periph.channels
1013                    xcu_arg      = periph.arg
1014                    nb_xcu +=1
1015
1016        # no more than two access to external peripherals
1017        assert ( nb_fbf <= 2 )
1018        assert ( nb_cma <= 2 )
1019        assert ( nb_ioc <= 2 )
1020        assert ( nb_nic <= 2 )
1021        assert ( nb_tim <= 2 )
1022        assert ( nb_tty <= 2 )
1023        assert ( nb_pic <= 2 )
1024
1025        # one and only one type of IOC controller
1026        nb_iocs = 0
1027        if use_hba         : nb_iocs += 1
1028        if use_bdv         : nb_iocs += 1
1029        if use_spi         : nb_iocs += 1
1030        if self.use_ramdisk: nb_iocs += 1
1031        assert ( nb_iocs == 1 )
1032
1033        # Compute total number of processors
1034        for cluster in self.clusters:
1035            nb_total_procs += len( cluster.procs )
1036
1037        # Compute physical addresses for BOOT vsegs
1038        boot_mapping_found   = False
1039        boot_code_found      = False
1040        boot_data_found      = False
1041        boot_stack_found     = False
1042
1043        for vseg in self.globs:
1044            if ( vseg.name == 'seg_boot_mapping' ):
1045                boot_mapping_base       = vseg.vbase
1046                boot_mapping_size       = vseg.vobjs[0].length
1047                boot_mapping_identity   = vseg.identity
1048                boot_mapping_found      = True
1049
1050            if ( vseg.name == 'seg_boot_code' ):
1051                boot_code_base          = vseg.vbase
1052                boot_code_size          = vseg.vobjs[0].length
1053                boot_code_identity      = vseg.identity
1054                boot_code_found         = True
1055
1056            if ( vseg.name == 'seg_boot_data' ):
1057                boot_data_base          = vseg.vbase
1058                boot_data_size          = vseg.vobjs[0].length
1059                boot_data_identity      = vseg.identity
1060                boot_data_found         = True
1061
1062            if ( vseg.name == 'seg_boot_stack' ):
1063                boot_stack_base         = vseg.vbase
1064                boot_stack_size         = vseg.vobjs[0].length
1065                boot_stack_identity     = vseg.identity
1066                boot_stack_found        = True
1067
1068        # check that BOOT vsegs are found and identity mapping
1069        if ( (boot_mapping_found == False) or (boot_mapping_identity == False) ):
1070             print '[genmap error] in hard_config() : seg_boot_mapping missing or not ident'
1071             sys.exit()
1072
1073        if ( (boot_code_found == False) or (boot_code_identity == False) ):
1074             print '[genmap error] in hard_config() : seg_boot_code missing or not ident'
1075             sys.exit()
1076
1077        if ( (boot_data_found == False) or (boot_data_identity == False) ):
1078             print '[genmap error] in hard_config() : seg_boot_data missing or not ident'
1079             sys.exit()
1080
1081        if ( (boot_stack_found == False) or (boot_stack_identity == False) ):
1082             print '[genmap error] in giet_vsegs() : seg_boot_stack missing or not ident'
1083             sys.exit()
1084
1085        # Search RAMDISK global vseg if required
1086        seg_rdk_base =  0xFFFFFFFF
1087        seg_rdk_size =  0
1088        seg_rdk_found = False
1089
1090        if self.use_ramdisk:
1091            for vseg in self.globs:
1092                if ( vseg.name == 'seg_ramdisk' ):
1093                    seg_rdk_base  = vseg.vbase
1094                    seg_rdk_size  = vseg.vobjs[0].length
1095                    seg_rdk_found = True
1096
1097            if ( seg_rdk_found == False ):
1098                print 'Error in hard_config() "seg_ramdisk" not found'
1099                sys.exit(1)
1100
1101        # build string
1102        s =  '/* Generated by genmap for %s */\n'  % self.name
1103        s += '\n'
1104        s += '#ifndef HARD_CONFIG_H\n'
1105        s += '#define HARD_CONFIG_H\n'
1106        s += '\n'
1107
1108        s += '/* General platform parameters */\n'
1109        s += '\n'
1110        s += '#define X_SIZE                 %d\n'    % self.x_size
1111        s += '#define Y_SIZE                 %d\n'    % self.y_size
1112        s += '#define X_WIDTH                %d\n'    % self.x_width
1113        s += '#define Y_WIDTH                %d\n'    % self.y_width
1114        s += '#define P_WIDTH                %d\n'    % self.p_width
1115        s += '#define X_IO                   %d\n'    % self.x_io
1116        s += '#define Y_IO                   %d\n'    % self.y_io
1117        s += '#define NB_PROCS_MAX           %d\n'    % self.nprocs
1118        s += '#define IRQ_PER_PROCESSOR      %d\n'    % self.irq_per_proc
1119        s += '#define RESET_ADDRESS          0x%x\n'  % self.reset_address
1120        s += '#define NB_TOTAL_PROCS         %d\n'    % nb_total_procs
1121        s += '\n'
1122
1123        s += '/* Peripherals */\n'
1124        s += '\n'
1125        s += '#define NB_TTY_CHANNELS        %d\n'    % tty_channels
1126        s += '#define NB_IOC_CHANNELS        %d\n'    % ioc_channels
1127        s += '#define NB_NIC_CHANNELS        %d\n'    % nic_channels
1128        s += '#define NB_CMA_CHANNELS        %d\n'    % cma_channels
1129        s += '#define NB_TIM_CHANNELS        %d\n'    % tim_channels
1130        s += '#define NB_DMA_CHANNELS        %d\n'    % dma_channels
1131        s += '\n'
1132        s += '#define USE_XCU                %d\n'    % ( nb_xcu != 0 )
1133        s += '#define USE_IOB                %d\n'    % ( nb_iob != 0 )
1134        s += '#define USE_PIC                %d\n'    % ( nb_pic != 0 )
1135        s += '#define USE_FBF                %d\n'    % ( nb_fbf != 0 )
1136        s += '\n'
1137        s += '#define USE_IOC_BDV            %d\n'    % use_bdv
1138        s += '#define USE_IOC_SPI            %d\n'    % use_spi
1139        s += '#define USE_IOC_HBA            %d\n'    % use_hba
1140        s += '#define USE_IOC_RDK            %d\n'    % self.use_ramdisk
1141        s += '\n'
1142        s += '#define FBUF_X_SIZE            %d\n'    % fbf_arg
1143        s += '#define FBUF_Y_SIZE            %d\n'    % fbf_arg
1144        s += '\n'
1145        s += '#define XCU_NB_INPUTS          %d\n'    % xcu_arg
1146        s += '\n'
1147
1148        s += '/* base addresses and sizes for physical segments */\n'
1149        s += '\n'
1150        s += '#define SEG_RAM_BASE           0x%x\n'  % self.ram_base
1151        s += '#define SEG_RAM_SIZE           0x%x\n'  % self.ram_size
1152        s += '\n'
1153        s += '#define SEG_CMA_BASE           0x%x\n'  % seg_cma_base
1154        s += '#define SEG_CMA_SIZE           0x%x\n'  % seg_cma_size
1155        s += '\n'
1156        s += '#define SEG_DMA_BASE           0x%x\n'  % seg_dma_base
1157        s += '#define SEG_DMA_SIZE           0x%x\n'  % seg_dma_size
1158        s += '\n'
1159        s += '#define SEG_FBF_BASE           0x%x\n'  % seg_fbf_base
1160        s += '#define SEG_FBF_SIZE           0x%x\n'  % seg_fbf_size
1161        s += '\n'
1162        s += '#define SEG_IOB_BASE           0x%x\n'  % seg_iob_base
1163        s += '#define SEG_IOB_SIZE           0x%x\n'  % seg_iob_size
1164        s += '\n'
1165        s += '#define SEG_IOC_BASE           0x%x\n'  % seg_ioc_base
1166        s += '#define SEG_IOC_SIZE           0x%x\n'  % seg_ioc_size
1167        s += '\n'
1168        s += '#define SEG_MMC_BASE           0x%x\n'  % seg_mmc_base
1169        s += '#define SEG_MMC_SIZE           0x%x\n'  % seg_mmc_size
1170        s += '\n'
1171        s += '#define SEG_MWR_BASE           0x%x\n'  % seg_mwr_base
1172        s += '#define SEG_MWR_SIZE           0x%x\n'  % seg_mwr_size
1173        s += '\n'
1174        s += '#define SEG_ROM_BASE           0x%x\n'  % seg_rom_base
1175        s += '#define SEG_ROM_SIZE           0x%x\n'  % seg_rom_size
1176        s += '\n'
1177        s += '#define SEG_SIM_BASE           0x%x\n'  % seg_sim_base
1178        s += '#define SEG_SIM_SIZE           0x%x\n'  % seg_sim_size
1179        s += '\n'
1180        s += '#define SEG_NIC_BASE           0x%x\n'  % seg_nic_base
1181        s += '#define SEG_NIC_SIZE           0x%x\n'  % seg_nic_size
1182        s += '\n'
1183        s += '#define SEG_PIC_BASE           0x%x\n'  % seg_pic_base
1184        s += '#define SEG_PIC_SIZE           0x%x\n'  % seg_pic_size
1185        s += '\n'
1186        s += '#define SEG_TIM_BASE           0x%x\n'  % seg_tim_base
1187        s += '#define SEG_TIM_SIZE           0x%x\n'  % seg_tim_size
1188        s += '\n'
1189        s += '#define SEG_TTY_BASE           0x%x\n'  % seg_tty_base
1190        s += '#define SEG_TTY_SIZE           0x%x\n'  % seg_tty_size
1191        s += '\n'
1192        s += '#define SEG_XCU_BASE           0x%x\n'  % seg_xcu_base
1193        s += '#define SEG_XCU_SIZE           0x%x\n'  % seg_xcu_size
1194        s += '\n'
1195        s += '#define SEG_RDK_BASE           0x%x\n'  % seg_rdk_base
1196        s += '#define SEG_RDK_SIZE           0x%x\n'  % seg_rdk_size
1197        s += '\n'
1198        s += '#define SEG_DROM_BASE          0x%x\n'  % seg_drom_base
1199        s += '#define SEG_DROM_SIZE          0x%x\n'  % seg_drom_size
1200        s += '\n'
1201        s += '#define PERI_CLUSTER_INCREMENT 0x%x\n'  % self.peri_increment
1202        s += '\n'
1203
1204        s += '/* physical base addresses for identity mapped vsegs */\n'
1205        s += '/* used by the GietVM OS                             */\n'
1206        s += '\n'
1207        s += '#define SEG_BOOT_MAPPING_BASE  0x%x\n'  % boot_mapping_base
1208        s += '#define SEG_BOOT_MAPPING_SIZE  0x%x\n'  % boot_mapping_size
1209        s += '\n'
1210        s += '#define SEG_BOOT_CODE_BASE     0x%x\n'  % boot_code_base
1211        s += '#define SEG_BOOT_CODE_SIZE     0x%x\n'  % boot_code_size
1212        s += '\n'
1213        s += '#define SEG_BOOT_DATA_BASE     0x%x\n'  % boot_data_base
1214        s += '#define SEG_BOOT_DATA_SIZE     0x%x\n'  % boot_data_size
1215        s += '\n'
1216        s += '#define SEG_BOOT_STACK_BASE    0x%x\n'  % boot_stack_base
1217        s += '#define SEG_BOOT_STACK_SIZE    0x%x\n'  % boot_stack_size
1218        s += '#endif\n'
1219
1220        return s
1221
1222    # end of hard_config()
1223
1224    ################################################################################
1225    def linux_dts( self ):     # compute string for linux.dts file generation
1226                               # used for linux configuration
1227        # header
1228        s =  '/dts-v1/;\n'
1229        s += '\n'
1230        s += '/{\n'
1231        s += '  compatible = "tsar,%s";\n' % self.name
1232        s += '  #address-cells = <2>;\n'               # physical address on 64 bits
1233        s += '  #size-cells    = <1>;\n'               # segment size on 32 bits
1234        s += '  model = "%s";\n' % self.name
1235        s += '\n'
1236
1237        # linux globals arguments
1238        s += '  chosen {\n'
1239        s += '    linux,stdout-path = &tty;\n'
1240        s += '    bootargs = "console=tty0 console=ttyVTTY0 earlyprintk";\n'
1241        s += '  };\n\n'
1242
1243        # cpus (for each cluster)
1244        s += '  cpus {\n'
1245        s += '    #address-cells = <1>;\n'
1246        s += '    #size-cells    = <0>;\n'
1247
1248        for cluster in self.clusters:
1249            for proc in cluster.procs:
1250                x       = cluster.x
1251                y       = cluster.y
1252                l       = proc.lpid
1253                proc_id = (((x << self.y_width) + y) << self.p_width) + l
1254                s += '    cpu@%d_%d_%d {\n' %(x,y,l)
1255                s += '      device_type = "cpu";\n'
1256                s += '      compatible = "soclib,mips32el";\n'
1257                s += '      reg = <0x%x>;\n' % proc_id
1258                s += '    };\n'
1259                s += '\n'
1260
1261        s += '  };\n\n'
1262
1263        # devices (ram or peripheral) are grouped per cluster
1264        # the "compatible" attribute links a peripheral device
1265        # to one or several drivers identified by ("major","minor")
1266
1267        for cluster in self.clusters:
1268            x               = cluster.x
1269            y               = cluster.y
1270            found_xcu       = False
1271            found_pic       = False
1272
1273            s += '  /*** cluster[%d,%d] ***/\n\n' % (x,y)
1274
1275            # scan all psegs to find RAM in current cluster
1276            for pseg in cluster.psegs:
1277                if ( pseg.segtype == 'RAM' ):
1278                    msb  = pseg.base >> 32
1279                    lsb  = pseg.base & 0xFFFFFFFF
1280                    size = pseg.size
1281
1282                    s += '  ram_%d_%d: ram@0x%x {\n' % (x, y, pseg.base)
1283                    s += '    device_type = "memory";\n'
1284                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1285                    s += '  };\n\n'
1286
1287            # scan all periphs to find XCU or PIC in current cluster
1288            for periph in cluster.periphs:
1289                msb     = periph.pseg.base >> 32
1290                lsb     = periph.pseg.base & 0xFFFFFFFF
1291                size    = periph.pseg.size
1292
1293                # search XCU (can be replicated)
1294                if ( (periph.ptype == 'XCU') ):
1295                    found_xcu     = True
1296                    xcu           = periph
1297                    irq_ctrl_name = 'xcu_%d_%d' % (x, y)
1298
1299                    s += %s: xcu@0x%x {\n'  % (irq_ctrl_name, periph.pseg.base)
1300                    s += '    compatible = "soclib,vci_xicu","soclib,vci_xicu_timer";\n'
1301                    s += '    interrupt-controller;\n'
1302                    s += '    #interrupt-cells = <1>;\n'
1303                    s += '    clocks = <&freq>;\n'         # the XCU component contains a timer
1304                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1305                    s += '  };\n\n'
1306
1307                # search PIC (non replicated)
1308                if ( periph.ptype == 'PIC' ):
1309                    found_pic     = True
1310                    pic           = periph
1311                    irq_ctrl_name = 'pic'
1312
1313                    s += %s: pic@0x%x {\n'  % (irq_ctrl_name, periph.pseg.base)
1314                    s += '    compatible = "soclib,vci_iopic";\n'
1315                    s += '    interrupt-controller;\n'
1316                    s += '    #interrupt-cells = <1>;\n'
1317                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1318                    s += '  };\n\n'
1319
1320            # we need one interrupt controler in any cluster containing peripherals
1321            if ( (found_xcu == False) and (found_pic == False) and (len(cluster.periphs) > 0) ):
1322                print '[genmap error] in linux_dts() : No XCU/PIC in cluster(%d,%d)' % (x,y)
1323                sys.exit(1)
1324
1325            if ( found_pic == True ): irq_ctrl = pic
1326            else:                     irq_ctrl = xcu
1327
1328            # scan all periphs to find TTY and IOC in current cluster
1329            for periph in cluster.periphs:
1330                msb     = periph.pseg.base >> 32
1331                lsb     = periph.pseg.base & 0xFFFFFFFF
1332                size    = periph.pseg.size
1333
1334                # search TTY (non replicated)
1335                if ( periph.ptype == 'TTY' ):
1336
1337                    # get HWI index to XCU or PIC (only TTY channel 0 is used by Linux)
1338                    hwi_id = 0xFFFFFFFF
1339                    for irq in irq_ctrl.irqs:
1340                        if ( (irq.isrtype == 'ISR_TTY_RX') and (irq.channel == 0) ): hwi_id = irq.srcid
1341                    if ( hwi_id == 0xFFFFFFFF ):
1342                        print '[genmap error] in linux.dts() IRQ_TTY_RX not found'
1343                        sys.exit(1)
1344
1345                    s += '  tty: tty {\n'
1346                    s += '    compatible = "soclib,vci_multi_tty";\n'
1347                    s += '    interrupt-parent = <&%s>;\n' % (irq_ctrl_name)
1348                    s += '    interrupts = <%d>;\n' % hwi_id
1349                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1350                    s += '  };\n\n'
1351
1352                # search IOC (non replicated)
1353                elif ( periph.ptype == 'IOC' ):
1354
1355                    if ( periph.subtype == 'BDV' ):
1356
1357                        # get irq line index associated to bdv
1358                        hwi_id = 0xFFFFFFFF
1359                        for irq in irq_ctrl.irqs:
1360                            if ( irq.isrtype == 'ISR_BDV' ): hwi_id = irq.srcid
1361                        if ( hwi_id == 0xFFFFFFFF ):
1362                            print '[genmap error] in linux.dts() ISR_BDV not found'
1363                            sys.exit(1)
1364
1365                        s += '  bdv: bdv {\n'
1366                        s += '    compatible = "soclib,vci_blockdevice";\n'
1367                        s += '    interrupt-parent = <&%s>;\n' % (irq_ctrl_name)
1368                        s += '    interrupts = <%d>;\n' % hwi_id
1369                        s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1370                        s += '  };\n\n'
1371
1372                    elif ( periph.subtype == 'HBA' ):
1373
1374                        print '[genmap error] in linux_dts() : HBA peripheral not supported by LINUX'
1375                        sys.exit(1)
1376
1377                    elif ( periph.subtype == 'SPI' ):
1378
1379                        print '[genmap error] in linux_dts() : SPI peripheral not supported by LINUX'
1380                        sys.exit(1)
1381
1382                # XCU or PIC have been already parsed
1383                elif ( periph.ptype == 'XCU' ) or ( periph.ptype == 'PIC' ):
1384                    pass
1385
1386                # other peripherals
1387                else:
1388                    type = periph.ptype
1389                    print '[genmap warning] in linux_dts() : %s peripheral not supported by LINUX' % (type)
1390
1391        # clocks
1392        s += '  /*** clocks ***/\n\n'
1393        s += '  clocks {\n'
1394        s += '    freq: freq@50MHZ {\n'
1395        s += '      #clock-cells = <0>;\n'
1396        s += '      compatible = "fixed-clock";\n'
1397        s += '      clock-frequency = <50000000>;\n'
1398        s += '    };\n'
1399        s += '  };\n\n'
1400        s += '  cpuclk {\n'
1401        s += '    compatible = "soclib,mips32_clksrc";\n'
1402        s += '    clocks = <&freq>;\n'
1403        s += '  };\n'
1404        s += '};\n'
1405
1406        return s
1407        # end linux_dts()
1408
1409
1410    #############################################################################
1411    def netbsd_dts( self ):    # compute string for netbsd.dts file generation,
1412                               # used for netbsd configuration
1413        # header
1414        s =  '/dts-v1/;\n'
1415        s += '\n'
1416        s += '/{\n'
1417        s += '  #address-cells = <2>;\n'
1418        s += '  #size-cells    = <1>;\n'
1419
1420        # cpus (for each cluster)
1421        s += '  cpus {\n'
1422        s += '    #address-cells = <1>;\n'
1423        s += '    #size-cells    = <0>;\n'
1424
1425        for cluster in self.clusters:
1426            for proc in cluster.procs:
1427                proc_id = (((cluster.x << self.y_width) + cluster.y) << self.p_width) + proc.lpid
1428
1429                s += '    Mips,32@0x%x {\n'                % proc_id
1430                s += '      device_type = "cpu";\n'
1431                s += '      icudev_type = "cpu:mips";\n'
1432                s += '      name        = "Mips,32";\n'
1433                s += '      reg         = <0x%x>;\n'     % proc_id
1434                s += '    };\n'
1435                s += '\n'
1436
1437        s += '  };\n'
1438
1439        # physical memory banks (for each cluster)
1440        for cluster in self.clusters:
1441            for pseg in cluster.psegs:
1442
1443                if ( pseg.segtype == 'RAM' ):
1444                    msb  = pseg.base >> 32
1445                    lsb  = pseg.base & 0xFFFFFFFF
1446                    size = pseg.size
1447
1448                    s += %s@0x%x {\n' % (pseg.name, pseg.base)
1449                    s += '    cached      = <1>;\n'
1450                    s += '    device_type = "memory";\n'
1451                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1452                    s += '  };\n'
1453
1454        # peripherals (for each cluster)
1455        for cluster in self.clusters:
1456            x = cluster.x
1457            y = cluster.y
1458
1459            # research XCU component
1460            found_xcu = False
1461            for periph in cluster.periphs:
1462                if ( (periph.ptype == 'XCU') ):
1463                    found_xcu = True
1464                    xcu = periph
1465                    msb  = periph.pseg.base >> 32
1466                    lsb  = periph.pseg.base & 0xFFFFFFFF
1467                    size = periph.pseg.size
1468
1469                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1470                    s += '    device_type = "soclib:xicu:root";\n'
1471                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1472                    s += '    input_lines = <%d>;\n'    % periph.arg
1473                    s += '    ipis        = <%d>;\n'    % periph.arg
1474                    s += '    timers      = <%d>;\n'    % periph.arg
1475
1476                    output_id = 0            # output index from XCU
1477                    for lpid in xrange ( len(cluster.procs) ):        # destination processor index
1478                        for itid in xrange ( self.irq_per_proc ):     # input irq index on processor
1479                            cluster_xy = (cluster.x << self.y_width) + cluster.y
1480                            proc_id    = (cluster_xy << self.p_width) + lpid
1481                            s += '    out@%d {\n' % output_id
1482                            s += '      device_type = "soclib:xicu:filter";\n'
1483                            s += '      irq = <&{/cpus/Mips,32@0x%x} %d>;\n' % (proc_id, itid)
1484                            s += '      output_line = <%d>;\n' % output_id
1485                            s += '      parent = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1486                            s += '    };\n'
1487
1488                            output_id += 1
1489
1490                    s += '  };\n'
1491
1492            # research PIC component
1493            found_pic = False
1494            for periph in cluster.periphs:
1495                if ( periph.ptype == 'PIC' ):
1496                    found_pic = True
1497                    pic  = periph
1498                    msb  = periph.pseg.base >> 32
1499                    lsb  = periph.pseg.base & 0xFFFFFFFF
1500                    size = periph.pseg.size
1501
1502                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1503                    s += '    device_type = "soclib:pic:root";\n'
1504                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1505                    s += '    input_lines = <%d>;\n'    % periph.channels
1506                    s += '  };\n'
1507
1508            # at least one interrupt controller
1509            if ( (found_xcu == False) and (found_pic == False) and (len(cluster.periphs) > 0) ):
1510                print '[genmap error] in netbsd_dts() : No XCU/PIC in cluster(%d,%d)' % (x,y)
1511                sys.exit(1)
1512
1513            if ( found_pic == True ):  irq_tgt = pic
1514            else:                      irq_tgt = xcu
1515
1516            # get all others peripherals in cluster
1517            for periph in cluster.periphs:
1518                msb  = periph.pseg.base >> 32
1519                lsb  = periph.pseg.base & 0xFFFFFFFF
1520                size = periph.pseg.size
1521
1522                # research DMA component
1523                if ( periph.ptype == 'DMA' ):
1524
1525                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1526                    s += '    device_type = "soclib:dma";\n'
1527                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1528                    s += '    channel_count = <%d>;\n' % periph.channels
1529
1530                    # multi-channels : get HWI index (to XCU) for each channel
1531                    for channel in xrange( periph.channels ):
1532                        hwi_id = 0xFFFFFFFF
1533                        for irq in xcu.irqs:
1534                            if ( (irq.isrtype == 'ISR_DMA') and (irq.channel == channel) ):
1535                                hwi_id = irq.srcid
1536                        if ( hwi_id == 0xFFFFFFFF ):
1537                            print '[genmap error] in netbsd.dts() ISR_DMA channel %d not found' % channel
1538                            sys.exit(1)
1539
1540                        name = '%s@0x%x' % (xcu.pseg.name, xcu.pseg.base)
1541                        s += '    irq@%d{\n' % channel
1542                        s += '      device_type = "soclib:periph:irq";\n'
1543                        s += '      output_line = <%d>;\n' % channel
1544                        s += '      irq = <&{/%s%d>;\n' % (name, hwi_id)
1545                        s += '      parent = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1546                        s += '    };\n'
1547
1548                    s += '  };\n'
1549
1550                # research MMC component
1551                elif ( periph.ptype == 'MMC' ):
1552
1553                    # get irq line index associated to MMC in XCU
1554                    irq_in = 0xFFFFFFFF
1555                    for irq in xcu.irqs:
1556                        if ( irq.isrtype == 'ISR_MMC' ): irq_in = irq.srcid
1557                    if ( irq_in == 0xFFFFFFFF ):
1558                        print '[genmap error] in netbsd.dts() ISR_MMC not found'
1559                        sys.exit(1)
1560
1561                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1562                    s += '    device_type = "soclib:mmc";\n'
1563                    s += '    irq = <&{/%s@0x%x%d>;\n' % (irq_tgt.pseg.name, irq_tgt.pseg.base, irq_in)
1564                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1565                    s += '  };\n'
1566
1567                # research FBF component
1568                elif ( periph.ptype == 'FBF' ):
1569
1570                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1571                    s += '    device_type = "soclib:framebuffer";\n'
1572                    s += '    mode        = <32>;\n'                    # bits par pixel
1573                    s += '    width       = <%d>;\n'    % periph.arg
1574                    s += '    height      = <%d>;\n'    % periph.arg
1575                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1576                    s += '  };\n'
1577
1578                # research IOC component
1579                elif ( periph.ptype == 'IOC' ):
1580
1581                    if   ( periph.subtype == 'BDV' ):
1582
1583                        # get irq line index associated to bdv
1584                        irq_in = 0xFFFFFFFF
1585                        for irq in irq_tgt.irqs:
1586                            if ( irq.isrtype == 'ISR_BDV' ): irq_in = irq.srcid
1587                        if ( irq_in == 0xFFFFFFFF ):
1588                            print '[genmap error] in netbsd.dts() ISR_BDV not found'
1589                            sys.exit(1)
1590
1591                        s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1592                        s += '    device_type = "soclib:blockdevice";\n'
1593                        s += '    irq = <&{/%s@0x%x} %d>;\n' % (irq_tgt.pseg.name,irq_tgt.pseg.base,irq_in)
1594                        s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1595                        s += '  };\n'
1596
1597                    elif ( periph.subtype == 'HBA' ):
1598                        print '[genmap error] in netbsd_dts() : HBA peripheral not supported by NetBSD'
1599                        sys.exit(1)
1600
1601                    elif ( periph.subtype == 'SPI' ):
1602
1603                        # get irq line index associated to spi
1604                        irq_in = 0xFFFFFFFF
1605                        for irq in irq_tgt.irqs:
1606                            if ( irq.isrtype == 'ISR_SPI' ): irq_in = irq.srcid
1607                        if ( irq_in == 0xFFFFFFFF ):
1608                            print '[genmap error] in netbsd.dts() ISR_SPI not found'
1609                            sys.exit(1)
1610
1611                        s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1612                        s += '    device_type = "soclib:spi";\n'
1613                        s += '    irq = <&{/%s@0x%x} %d>;\n' % (irq_tgt.pseg.name,irq_tgt.pseg.base,irq_in)
1614                        s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1615                        s += '  };\n'
1616
1617                # research ROM component
1618                elif ( periph.ptype == 'ROM' ):
1619
1620                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1621                    s += '    device_type = "rom";\n'
1622                    s += '    cached = <1>;\n'
1623                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1624                    s += '  };\n'
1625
1626                # research SIM component
1627                elif ( periph.ptype == 'SIM' ):
1628
1629                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1630                    s += '    device_type = "soclib:simhelper";\n'
1631                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1632                    s += '  };\n'
1633
1634                # research TTY component
1635                elif ( periph.ptype == 'TTY' ):
1636
1637                    s += %s@0x%x {\n' % (periph.pseg.name, periph.pseg.base)
1638                    s += '    device_type = "soclib:tty";\n'
1639                    s += '    channel_count = < %d >;\n' % periph.channels
1640                    s += '    reg = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1641
1642                    # multi-channels : get HWI index (to XCU or PIC) for each channel
1643                    for channel in xrange( periph.channels ):
1644                        hwi_id = 0xFFFFFFFF
1645                        for irq in irq_tgt.irqs:
1646                            if ( (irq.isrtype == 'ISR_TTY_RX') and (irq.channel == channel) ):
1647                                hwi_id = irq.srcid
1648                        if ( hwi_id == 0xFFFFFFFF ):
1649                            print '[genmap error] in netbsd.dts() ISR_TTY_RX channel %d not found' % channel
1650                            sys.exit(1)
1651
1652                        name = '%s@0x%x' % (irq_tgt.pseg.name, irq_tgt.pseg.base)
1653                        s += '    irq@%d{\n' % channel
1654                        s += '      device_type = "soclib:periph:irq";\n'
1655                        s += '      output_line = <%d>;\n' % channel
1656                        s += '      irq = <&{/%s%d>;\n' % (name, hwi_id)
1657                        s += '      parent = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1658                        s += '    };\n'
1659
1660                    s += '  };\n'
1661
1662                # research IOB component
1663                elif ( periph.ptype == 'IOB' ):
1664
1665                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1666                    s += '    device_type = "soclib:iob";\n'
1667                    s += '    reg         = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1668                    s += '  };\n'
1669
1670                # research NIC component
1671                elif ( periph.ptype == 'NIC' ):
1672
1673                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1674                    s += '    device_type   = "soclib:nic";\n'
1675                    s += '    reg           = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1676                    s += '    channel_count = < %d >;\n' % periph.channels
1677
1678                    # multi-channels : get HWI index (to XCU or PIC) for RX & TX IRQs
1679                    # RX IRQ : (2*channel) / TX IRQs : (2*channel + 1)
1680                    for channel in xrange( periph.channels ):
1681                        hwi_id = 0xFFFFFFFF
1682                        for irq in irq_tgt.irqs:
1683                            if ( (irq.isrtype == 'ISR_NIC_RX') and (irq.channel == channel) ):
1684                                hwi_id = irq.srcid
1685                        if ( hwi_id == 0xFFFFFFFF ):
1686                            print '[genmap error] in netbsd.dts() ISR_NIC_RX channel %d not found' % channel
1687                            sys.exit(1)
1688
1689                        name = '%s@0x%x' % (irq_tgt.pseg.name, irq_tgt.pseg.base)
1690                        s += '    irq_rx@%d{\n' % channel
1691                        s += '      device_type = "soclib:periph:irq";\n'
1692                        s += '      output_line = <%d>;\n' % (2*channel)
1693                        s += '      irq         = <&{/%s%d>;\n' % (name, hwi_id)
1694                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1695                        s += '    };\n'
1696
1697                        hwi_id = 0xFFFFFFFF
1698                        for irq in irq_tgt.irqs:
1699                            if ( (irq.isrtype == 'ISR_NIC_TX') and (irq.channel == channel) ):
1700                                hwi_id = irq.srcid
1701                        if ( hwi_id == 0xFFFFFFFF ):
1702                            print '[genmap error] in netbsd.dts() ISR_NIC_TX channel %d not found' % channel
1703                            sys.exit(1)
1704
1705                        name = '%s@0x%x' % (irq_tgt.pseg.name, irq_tgt.pseg.base)
1706                        s += '    irq_tx@%d{\n' % channel
1707                        s += '      device_type = "soclib:periph:irq";\n'
1708                        s += '      output_line = <%d>;\n' % (2*channel + 1)
1709                        s += '      irq         = <&{/%s%d>;\n' % (name, hwi_id)
1710                        s += '      parent      = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1711                        s += '    };\n'
1712
1713                    s += '  };\n'
1714
1715                # research CMA component
1716                elif ( periph.ptype == 'CMA' ):
1717
1718                    s += %s@0x%x {\n'  % (periph.pseg.name, periph.pseg.base)
1719                    s += '    device_type   = "soclib:cma";\n'
1720                    s += '    reg           = <0x%x  0x%x  0x%x>;\n' % (msb, lsb, size)
1721                    s += '    channel_count = < %d >;\n' % periph.channels
1722
1723                    # multi-channels : get HWI index (to XCU or PIC) for each channel
1724                    for channel in xrange( periph.channels ):
1725                        hwi_id = 0xFFFFFFFF
1726                        for irq in irq_tgt.irqs:
1727                            if ( (irq.isrtype == 'ISR_CMA') and (irq.channel == channel) ):
1728                                hwi_id = irq.srcid
1729                        if ( hwi_id == 0xFFFFFFFF ):
1730                            print '[genmap error] in netbsd.dts() ISR_CMA channel %d not found' % channel
1731                            sys.exit(1)
1732
1733                        name = '%s@0x%x' % (irq_tgt.pseg.name, irq_tgt.pseg.base)
1734                        s += '    irq@%d{\n' % channel
1735                        s += '      device_type = "soclib:periph:irq";\n'
1736                        s += '      output_line = <%d>;\n' % channel
1737                        s += '      irq = <&{/%s%d>;\n' % (name, hwi_id)
1738                        s += '      parent = <&{/%s@0x%x}>;\n' % (periph.pseg.name, periph.pseg.base)
1739                        s += '    };\n'
1740
1741                    s += '  };\n'
1742
1743                # research TIM component
1744                elif ( periph.ptype == 'TIM' ):
1745
1746                    print '[genmap error] in netbsd_dts() : TIM peripheral not supported by NetBSD'
1747                    sys.exit(1)
1748
1749                # research MWR component
1750                elif ( periph.ptype == 'MWR' ):
1751
1752                    print '[genmap error] in netbsd_dts() : MWR peripheral not supported by NetBSD'
1753                    sys.exit(1)
1754
1755        # topology
1756        s += '\n'
1757        s += '  topology {\n'
1758        s += '    #address-cells = <2>;\n'
1759        s += '    #size-cells = <0>;\n'
1760        for cluster in self.clusters:
1761            s += '    cluster@%d,%d {\n' % (cluster.x, cluster.y)
1762            s += '      reg     = <%d %d>;\n' % (cluster.x, cluster.y)
1763            s += '      devices = <\n'
1764
1765            offset = ((cluster.x << self.y_width) + cluster.y) << self.p_width
1766            for proc in cluster.procs:
1767                s += '                &{/cpus/Mips,32@0x%x}\n' % (offset + proc.lpid)
1768            for periph in cluster.periphs:
1769                s += '                &{/%s@0x%x}\n' % (periph.pseg.name, periph.pseg.base)
1770            for pseg in cluster.psegs:
1771                if ( pseg.segtype == 'RAM' ):
1772                    s += '                &{/%s@0x%x}\n' % (pseg.name, pseg.base)
1773
1774            s += '                >;\n'
1775            s += '    };\n'
1776        s += '  };\n'
1777        s += '};\n'
1778
1779        return s
1780        # end netbsd_dts()
1781
1782    ###########################
1783    def almos_archinfo( self ):    # compute string for arch.info file generation,
1784                                   # used for almos configuration
1785        # header
1786        s =  '# arch.info file generated by genmap for %s\n' % self.name
1787        s += '\n'
1788        s += '[HEADER]\n'
1789        s += '        REVISION=1\n'
1790        s += '        ARCH=%s\n'            % self.name
1791        s += '        XMAX=%d\n'            % self.x_size
1792        s += '        YMAX=%d\n'            % self.y_size
1793        s += '        CPU_NR=%d\n'          % self.nprocs
1794        s += '\n'
1795
1796        # clusters
1797        cluster_id = 0
1798        for cluster in self.clusters:
1799
1800            ram = None
1801            nb_cpus = len( cluster.procs )
1802            nb_devs = len( cluster.periphs )
1803            if ( len( cluster.coprocs ) != 0 ):
1804                print 'Error in almos_archinfo() coprocessors not supported yet'
1805                sys.exit(1)
1806
1807            # search a RAM
1808            for pseg in cluster.psegs:
1809                if ( pseg.segtype == 'RAM' ):
1810                    ram     = pseg
1811                    nb_devs += 1
1812
1813            # search XCU to get IRQs indexes if cluster contains peripherals
1814            if ( len( cluster.periphs ) != 0 ):
1815                tty_irq_id = None
1816                bdv_irq_id = None
1817                dma_irq_id = None
1818
1819                for periph in cluster.periphs:
1820                    if ( periph.ptype == 'XCU' ):
1821                        # scan irqs
1822                        for irq in periph.irqs:
1823                            if ( irq.isrtype == 'ISR_TTY_RX' ) : tty_irq_id = irq.srcid
1824                            if ( irq.isrtype == 'ISR_BDV'    ) : bdv_irq_id = irq.srcid
1825                            if ( irq.isrtype == 'ISR_DMA'    ) : dma_irq_id = irq.srcid
1826
1827            # Build the cluster description
1828            s += '[CLUSTER]\n'
1829            s += '         CID=%d\n'        % cluster_id
1830            s += '         ARCH_CID=0x%x\n' % ((cluster.x << self.y_width) + cluster.y)
1831            s += '         CPU_NR=%d\n'     % nb_cpus
1832            s += '         DEV_NR=%d\n'     % nb_devs
1833
1834
1835            # Handling RAM when cluster contain a RAM
1836            if (ram != None ):
1837                base  = ram.base
1838                size  = ram.size
1839                irqid = -1
1840                s += '         DEVID=RAM'
1841                s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % ( base, size )
1842
1843            # Handling peripherals
1844            for periph in cluster.periphs:
1845                base  = periph.pseg.base
1846                size  = periph.pseg.size
1847
1848                if   ( periph.ptype == 'XCU' ):
1849
1850                    s += '         DEVID=XICU'
1851                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % ( base, size )
1852
1853                elif ( (periph.ptype == 'TTY')
1854                       and (tty_irq_id != None) ):
1855
1856                    s += '         DEVID=TTY'
1857                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' % ( base, size, tty_irq_id )
1858
1859                elif ( (periph.ptype == 'DMA')
1860                       and (dma_irq_id != None) ):
1861
1862                    s += '         DEVID=DMA'
1863                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' % ( base, size, dma_irq_id )
1864
1865                elif ( periph.ptype == 'FBF' ):
1866
1867                    s += '         DEVID=FB'
1868                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % ( base, size )
1869
1870                elif ( (periph.ptype == 'IOC') and (periph.subtype == 'BDV')
1871                       and (bdv_irq_id != None) ):
1872
1873                    s += '         DEVID=BLKDEV'
1874                    s += '  BASE=0x%x  SIZE=0x%x  IRQ=%d\n' % ( base, size, bdv_irq_id )
1875
1876                elif ( periph.ptype == 'PIC' ):
1877
1878                        s += '         DEVID=IOPIC'
1879                        s += '  BASE=0x%x  SIZE=0x%x  IRQ=-1\n' % ( base, size )
1880
1881                else:
1882                    print '# Warning from almos_archinfo() in cluster[%d,%d]' \
1883                          % (cluster.x, cluster.y)
1884                    print '# peripheral type %s/%s not supported yet\n' \
1885                          % ( periph.ptype, periph.subtype )
1886
1887            cluster_id += 1
1888
1889        return s
1890
1891    # end of almos_archinfo()
1892
1893
1894
1895
1896
1897
1898
1899
1900###########################################################################################
1901class Cluster ( object ):
1902###########################################################################################
1903    def __init__( self,
1904                  x,
1905                  y ):
1906
1907        self.index       = 0             # global index (set by Mapping constructor)
1908        self.x           = x             # x coordinate
1909        self.y           = y             # y coordinate
1910        self.psegs       = []            # filled by addRam() or addPeriph()
1911        self.procs       = []            # filled by addProc()
1912        self.coprocs     = []            # filled by addCoproc()
1913        self.periphs     = []            # filled by addPeriph()
1914
1915        return
1916
1917    ################
1918    def xml( self ):  # xml for a cluster
1919
1920        s = '        <cluster x="%d" y="%d" >\n' % (self.x, self.y)
1921        for pseg in self.psegs:   s += pseg.xml()
1922        for proc in self.procs:   s += proc.xml()
1923        for copr in self.coprocs: s += copr.xml()
1924        for peri in self.periphs: s += peri.xml()
1925        s += '        </cluster>\n'
1926
1927        return s
1928
1929    #############################################
1930    def cbin( self, mapping, verbose, expected ):    # C binary structure for Cluster
1931
1932        if ( verbose ):
1933            print '*** cbin for cluster [%d,%d]' % (self.x, self.y)
1934
1935        # check index
1936        if (self.index != expected):
1937            print '[genmap error] in Cluster.cbin() : cluster global index = %d / expected = %d' \
1938                  % (self.index, expected )
1939            sys.exit(1)
1940
1941        # compute global index for first pseg
1942        if ( len(self.psegs) > 0 ):
1943            pseg_id = self.psegs[0].index
1944        else:
1945            pseg_id = 0
1946
1947        # compute global index for first proc
1948        if ( len(self.procs) > 0 ):
1949            proc_id = self.procs[0].index
1950        else:
1951            proc_id = 0
1952
1953        # compute global index for first coproc
1954        if ( len(self.coprocs) > 0 ):
1955            coproc_id = self.coprocs[0].index
1956        else:
1957            coproc_id = 0
1958
1959        # compute global index for first periph
1960        if ( len(self.periphs) > 0 ):
1961            periph_id = self.periphs[0].index
1962        else:
1963            periph_id = 0
1964
1965        byte_stream = bytearray()
1966        byte_stream += mapping.int2bytes( 4 , self.x )                 # x coordinate
1967        byte_stream += mapping.int2bytes( 4 , self.y )                 # x coordinate
1968        byte_stream += mapping.int2bytes( 4 , len( self.psegs ) )      # number of psegs in cluster
1969        byte_stream += mapping.int2bytes( 4 , pseg_id )                # first pseg global index
1970        byte_stream += mapping.int2bytes( 4 , len( self.procs ) )      # number of procs in cluster
1971        byte_stream += mapping.int2bytes( 4 , proc_id )                # first proc global index
1972        byte_stream += mapping.int2bytes( 4 , len( self.coprocs ) )    # number of coprocs in cluster
1973        byte_stream += mapping.int2bytes( 4 , coproc_id )              # first coproc global index
1974        byte_stream += mapping.int2bytes( 4 , len( self.periphs ) )    # number of periphs in cluster
1975        byte_stream += mapping.int2bytes( 4 , periph_id )              # first periph global index
1976
1977        if ( verbose ):
1978            print 'nb_psegs   = %d' %  len( self.psegs )
1979            print 'pseg_id    = %d' %  pseg_id
1980            print 'nb_procs   = %d' %  len( self.procs )
1981            print 'proc_id    = %d' %  proc_id
1982            print 'nb_coprocs = %d' %  len( self.coprocs )
1983            print 'coproc_id  = %d' %  coproc_id
1984            print 'nb_periphs = %d' %  len( self.periphs )
1985            print 'periph_id  = %d' %  periph_id
1986
1987        return byte_stream
1988
1989###########################################################################################
1990class Vspace( object ):
1991###########################################################################################
1992    def __init__( self,
1993                  name,
1994                  startname ):
1995
1996        self.index     = 0              # global index ( set by addVspace() )
1997        self.name      = name           # vspace name
1998        self.startname = startname      # name of vobj containing the start_vector
1999        self.vsegs     = []
2000        self.tasks     = []
2001
2002        return
2003
2004    ################
2005    def xml( self ):   # xml for one vspace
2006
2007        s =  '        <vspace name="%s" startname="%s" >\n' % ( self.name, self.startname )
2008        for vseg in self.vsegs: s += vseg.xml()
2009        for task in self.tasks: s += task.xml()
2010        s += '        </vspace>\n'
2011
2012        return s
2013
2014    #############################################
2015    def cbin( self, mapping, verbose, expected ):   # C binary structure for Vspace
2016
2017        if ( verbose ):
2018            print '*** cbin for vspace %s' % (self.name)
2019
2020        # check index
2021        if (self.index != expected):
2022            print '[genmap error] in Vspace.cbin() : vspace global index = %d / expected = %d' \
2023                  % (self.index, expected )
2024            sys.exit(1)
2025
2026        # compute global index for vobj containing start_vector
2027        vobj_start_id = 0xFFFFFFFF
2028        for vseg in self.vsegs:
2029            if ( vseg.vobjs[0].name == self.startname ):
2030                vobj_start_id = vseg.vobjs[0].index
2031        if ( vobj_start_id == 0xFFFFFFFF ):
2032            print '[genmap error] in Vspace.cbin() : startname %s not found for vspace %s' \
2033                  % ( self.startname, self.name )
2034            sys.exit(1)
2035
2036        # compute first vseg, vobj, task global index
2037        first_vseg_id = self.vsegs[0].index
2038        first_vobj_id = self.vsegs[0].vobjs[0].index
2039        first_task_id = self.tasks[0].index
2040
2041        # compute number of vobjs, tasks, vsegs
2042        nb_vsegs = len( self.vsegs )
2043        nb_tasks = len( self.tasks )
2044        nb_vobjs = 0
2045        for vseg in self.vsegs:
2046            nb_vobjs += len( vseg.vobjs )
2047
2048        byte_stream = bytearray()
2049        byte_stream += mapping.str2bytes( 32, self.name )         # vspace name
2050        byte_stream += mapping.int2bytes( 4,  vobj_start_id )     # vobj start_vector
2051        byte_stream += mapping.int2bytes( 4,  nb_vsegs )          # number of vsegs
2052        byte_stream += mapping.int2bytes( 4,  nb_vobjs )          # number of vobjs
2053        byte_stream += mapping.int2bytes( 4,  nb_tasks )          # number of tasks
2054        byte_stream += mapping.int2bytes( 4,  first_vseg_id )     # first vseg global index
2055        byte_stream += mapping.int2bytes( 4,  first_vobj_id )     # first vobj global index
2056        byte_stream += mapping.int2bytes( 4,  first_task_id )     # first task global index
2057
2058        if ( verbose ):
2059            print 'start_id   = %d' %  vobj_start_id
2060            print 'nb_vsegs   = %d' %  nb_vsegs
2061            print 'nb_vobjs   = %d' %  nb_vobjs
2062            print 'nb_tasks   = %d' %  nb_tasks
2063            print 'vseg_id    = %d' %  first_vseg_id
2064            print 'vobj_id    = %d' %  first_vobj_id
2065            print 'task_id    = %d' %  first_task_id
2066
2067        return byte_stream
2068
2069###########################################################################################
2070class Task( object ):
2071###########################################################################################
2072    def __init__( self,
2073                  name,
2074                  trdid,
2075                  x,
2076                  y,
2077                  p,
2078                  stackname,
2079                  heapname,
2080                  startid ):
2081
2082        self.index     = 0             # global index value set by addTask()
2083        self.name      = name          # tsk name
2084        self.trdid     = trdid         # task index (unique in vspace)
2085        self.x         = x             # cluster x coordinate
2086        self.y         = y             # cluster y coordinate
2087        self.p         = p             # processor local index
2088        self.stackname = stackname     # name of vobj containing the stack
2089        self.heapname  = heapname      # name of vobj containing the heap
2090        self.startid   = startid       # index in start_vector
2091        return
2092
2093    ################
2094    def xml( self ):    # xml for one task
2095
2096        s =  '            <task name="%s"' % self.name
2097        s += ' trdid="%d"'                 % self.trdid
2098        s += ' x="%d"'                     % self.x
2099        s += ' y="%d"'                     % self.y
2100        s += ' p="%d"'                     % self.p
2101        s += ' stackname="%s"'             % self.stackname
2102        s += ' heapname="%s"'              % self.heapname
2103        s += ' startid="%d"'               % self.startid
2104        s += ' />\n'
2105
2106        return s
2107
2108    #####################################################
2109    def cbin( self, mapping, verbose, expected, vspace ):  # C binary data structure for Task
2110
2111        if ( verbose ):
2112            print '*** cbin for task %s in vspace %s' % (self.name, vspace.name)
2113
2114        # check index
2115        if (self.index != expected):
2116            print '[genmap error] in Task.cbin() : task global index = %d / expected = %d' \
2117                  % (self.index, expected )
2118            sys.exit(1)
2119
2120        # compute cluster global index
2121        cluster_id = (self.x * mapping.y_size) + self.y
2122
2123        # compute vobj local index for stack
2124        vobj_stack_id = 0xFFFFFFFF
2125        for vseg in vspace.vsegs:
2126            if ( vseg.vobjs[0].name == self.stackname ):
2127                vobj_stack_id = vseg.vobjs[0].index
2128        if ( vobj_stack_id == 0xFFFFFFFF ):
2129            print '[genmap error] in Task.cbin() : stackname %s not found for task %s in vspace %s' \
2130                  % ( self.stackname, self.name, vspace.name )
2131            sys.exit(1)
2132
2133        # compute vobj local index for heap
2134        if ( self.heapname == '' ):
2135            vobj_heap_id = 0
2136        else:
2137            vobj_heap_id = 0xFFFFFFFF
2138            for vseg in vspace.vsegs:
2139                if ( vseg.vobjs[0].name == self.heapname ):
2140                    vobj_heap_id = vseg.vobjs[0].index
2141            if ( vobj_heap_id == 0xFFFFFFFF ):
2142                print '[genmap error] in Task.cbin() : heapname %s not found for task %s in vspace %s' \
2143                      % ( self.heapname, self.name, vspace.name )
2144                sys.exit(1)
2145
2146        byte_stream = bytearray()
2147        byte_stream += mapping.str2bytes( 32, self.name )       # task name in vspace
2148        byte_stream += mapping.int2bytes( 4,  cluster_id )      # cluster global index
2149        byte_stream += mapping.int2bytes( 4,  self.p )          # processor local index in cluster
2150        byte_stream += mapping.int2bytes( 4,  self.trdid )      # thread local index in vspace
2151        byte_stream += mapping.int2bytes( 4,  vobj_stack_id )   # stack vobj local index
2152        byte_stream += mapping.int2bytes( 4,  vobj_heap_id )    # heap vobj local index
2153        byte_stream += mapping.int2bytes( 4,  self.startid )    # index in start vector
2154
2155        if ( verbose ):
2156            print 'clusterid  = %d' %  cluster_id
2157            print 'lpid       = %d' %  self.p
2158            print 'trdid      = %d' %  self.trdid
2159            print 'stackid    = %d' %  vobj_stack_id
2160            print 'heapid     = %d' %  vobj_heap_id
2161            print 'startid    = %d' %  self.startid
2162
2163        return byte_stream
2164
2165###########################################################################################
2166class Vseg( object ):
2167###########################################################################################
2168    def __init__( self,
2169                  name,
2170                  vbase,
2171                  mode,
2172                  x,
2173                  y,
2174                  psegname,
2175                  identity = False,
2176                  local    = False,
2177                  big      = False ):
2178
2179        assert mode in VSEGMODES
2180
2181        self.index    = 0                   # global index ( set by addVseg() )
2182        self.name     = name                # vseg name
2183        self.vbase    = vbase & 0xFFFFFFFF  # virtual base address in vspace
2184        self.mode     = mode                # CXWU access rights
2185        self.x        = x                   # x coordinate of destination cluster
2186        self.y        = y                   # y coordinate of destination cluster
2187        self.psegname = psegname            # name of pseg in destination cluster
2188        self.identity = identity            # identity mapping required
2189        self.local    = local               # only mapped in local PTAB when true
2190        self.big      = big                 # to be mapped in a big physical page
2191        self.vobjs    = []
2192        return
2193
2194    ################
2195    def xml( self ):  # xml for one vseg
2196
2197        s =  '            <vseg name="%s" vbase="0x%x" mode="%s" x="%d" y="%d" psegname="%s"' \
2198             % ( self.name, self.vbase, self.mode, self.x, self.y, self.psegname )
2199        if ( self.identity ): s += ' ident="1"'
2200        if ( self.local ):    s += ' local="1"'
2201        if ( self.big ):      s += ' big="1"'
2202        s += ' >\n'
2203        for vobj in self.vobjs:  s += vobj.xml()
2204        s += '            </vseg>\n'
2205
2206        return s
2207
2208    #############################################
2209    def cbin( self, mapping, verbose, expected ):    # C binary structure for Vseg
2210
2211        if ( verbose ):
2212            print '*** cbin for vseg[%d] %s' % (self.index, self.name)
2213
2214        # check index
2215        if (self.index != expected):
2216            print '[genmap error] in Vseg.cbin() : vseg global index = %d / expected = %d' \
2217                  % (self.index, expected )
2218            sys.exit(1)
2219
2220        # compute pseg_id
2221        pseg_id = 0xFFFFFFFF
2222        cluster_id = (self.x * mapping.y_size) + self.y
2223        cluster = mapping.clusters[cluster_id]
2224        for pseg in cluster.psegs:
2225            if (self.psegname == pseg.name):
2226                pseg_id = pseg.index
2227        if (pseg_id == 0xFFFFFFFF):
2228            print '[genmap error] in Vseg.cbin() : psegname %s not found for vseg %s in cluster %d' \
2229                  % ( self.psegname, self.name, cluster_id )
2230            sys.exit(1)
2231
2232        # compute numerical value for mode
2233        mode_id = 0xFFFFFFFF
2234        for x in xrange( len(VSEGMODES) ):
2235            if ( self.mode == VSEGMODES[x] ):
2236                mode_id = x
2237        if ( mode_id == 0xFFFFFFFF ):
2238            print '[genmap error] in Vseg.cbin() : undefined vseg mode %s' % self.mode
2239            sys.exit(1)
2240
2241        # compute vobj_id
2242        vobj_id = self.vobjs[0].index
2243
2244        byte_stream = bytearray()
2245        byte_stream += mapping.str2bytes( 32, self.name )       # vseg name
2246        byte_stream += mapping.int2bytes( 4,  self.vbase )      # virtual base address
2247        byte_stream += mapping.int2bytes( 8,  0 )               # physical base address
2248        byte_stream += mapping.int2bytes( 4,  0 )               # vseg size (bytes)
2249        byte_stream += mapping.int2bytes( 4,  pseg_id )         # physical segment global index
2250        byte_stream += mapping.int2bytes( 4,  mode_id )         # CXWU flags
2251        byte_stream += mapping.int2bytes( 4,  len(self.vobjs) ) # number of vobjs in vseg
2252        byte_stream += mapping.int2bytes( 4,  vobj_id )         # first vobj global index
2253        byte_stream += mapping.int2bytes( 4,  0 )               # linked list of vsegs on pseg
2254        byte_stream += mapping.int2bytes( 1,  0 )               # mapped when non zero
2255        byte_stream += mapping.int2bytes( 1,  self.identity )   # identity mapping if non zero
2256        byte_stream += mapping.int2bytes( 1,  self.local )      # only mapped in local PTAB
2257        byte_stream += mapping.int2bytes( 1,  self.big )        # to be mapped in big physical page
2258
2259        if ( verbose ):
2260            print 'vbase      = %x' %  self.vbase
2261            print 'pseg_id    = %d' %  pseg_id
2262            print 'mode       = %s' %  self.mode
2263            print 'nb_vobjs   = %d' %  len(self.vobjs)
2264            print 'vobj_id    = %d' %  vobj_id
2265
2266        return byte_stream
2267
2268###########################################################################################
2269class Vobj( object ):
2270###########################################################################################
2271    def __init__( self,
2272                  name,
2273                  length,
2274                  vtype,
2275                  binpath = '',
2276                  align   = 0,
2277                  init    = 0 ):
2278
2279        assert vtype in ['ELF','BLOB','PTAB','PERI','MWMR','LOCK', \
2280                         'BUFFER','BARRIER','CONST','MEMSPACE','SCHED','HEAP']
2281
2282        assert (vtype != 'ELF') or (binpath != '')
2283
2284        self.index    = 0        # global index ( set by addVobj() )
2285        self.name     = name     # vobj name (unique in vspace)
2286        self.vtype    = vtype    # vobj type (defined in mapping_info.h)
2287        self.length   = length   # vobj size (bytes)
2288        self.binpath  = binpath  # pathname for (ELF type)
2289        self.align    = align    # required alignment (logarithm of 2)
2290        self.init     = init     # initialisation value (for BARRIER or MWMR types)
2291
2292        return
2293
2294    ################
2295    def xml( self ):  # xml for a vobj
2296
2297        s = '            <vobj name="%s" type="%s" length="0x%x"' \
2298                           % ( self.name, self.vtype, self.length )
2299        if (self.binpath != ''):   s += ' binpath="%s"' % (self.binpath)
2300        if (self.align   != 0 ):   s += ' align="%d"' % (self.align)
2301        if (self.init    != 0 ):   s += ' init="%d"' % (self.init)
2302        s += ' />\n'
2303
2304        return s
2305
2306    #############################################
2307    def cbin( self, mapping, verbose, expected ):    # C binary structure for Vobj
2308
2309        # check index
2310        if (self.index != expected):
2311            print '[genmap error] in Vobj.cbin() : vobj global index = %d / expected = %d' \
2312                  % (self.index, expected )
2313            sys.exit(1)
2314        elif ( verbose ):
2315            print '*** cbin for vobj[%d] %s' % (self.index, self.name)
2316
2317        # compute numerical value for vtype
2318        vtype_int = 0xFFFFFFFF
2319        for x in xrange( len(VOBJTYPES) ):
2320            if ( self.vtype == VOBJTYPES[x] ):
2321                vtype_int = x
2322        if ( vtype_int == 0xFFFFFFFF ):
2323            print '[genmap error] in Vobj.cbin() : undefined vobj type %s' % self.vtype
2324            sys.exit(1)
2325
2326        byte_stream = bytearray()
2327        byte_stream += mapping.str2bytes( 32, self.name )       # vobj name
2328        byte_stream += mapping.str2bytes( 64, self.binpath )    # pathname for .elf file
2329        byte_stream += mapping.int2bytes( 4 , vtype_int )       # vobj type
2330        byte_stream += mapping.int2bytes( 4 , self.length )     # vobj size
2331        byte_stream += mapping.int2bytes( 4 , self.align )      # required alignment
2332        byte_stream += mapping.int2bytes( 4 , 0 )               # virtual base address
2333        byte_stream += mapping.int2bytes( 4 , self.init )       # init value
2334
2335        if ( verbose ):
2336            print 'binpath    = %s' %  self.binpath
2337            print 'type       = %s' %  self.vtype
2338            print 'length     = %x' %  self.length
2339
2340        return byte_stream
2341
2342###########################################################################################
2343class Processor ( object ):
2344###########################################################################################
2345    def __init__( self,
2346                  x,
2347                  y,
2348                  lpid ):
2349
2350        self.index    = 0      # global index ( set by addProc() )
2351        self.x        = x      # x cluster coordinate
2352        self.y        = y      # y cluster coordinate
2353        self.lpid     = lpid   # processor local index
2354
2355        return
2356
2357    ################
2358    def xml( self ):   # xml for a processor
2359        return '            <proc index="%d" />\n' % (self.lpid)
2360
2361    #############################################
2362    def cbin( self, mapping, verbose, expected ):    # C binary structure for Proc
2363
2364        if ( verbose ):
2365            print '*** cbin for proc %d in cluster (%d,%d)' % (self.lpid, self.x, self.y)
2366
2367        # check index
2368        if (self.index != expected):
2369            print '[genmap error] in Proc.cbin() : proc global index = %d / expected = %d' \
2370                  % (self.index, expected )
2371            sys.exit(1)
2372
2373        byte_stream = bytearray()
2374        byte_stream += mapping.int2bytes( 4 , self.lpid )       # local index
2375
2376        return byte_stream
2377
2378###########################################################################################
2379class Pseg ( object ):
2380###########################################################################################
2381    def __init__( self,
2382                  name,
2383                  base,
2384                  size,
2385                  x,
2386                  y,
2387                  segtype ):
2388
2389        assert( segtype in PSEGTYPES )
2390
2391        self.index    = 0       # global index ( set by addPseg() )
2392        self.name     = name    # pseg name (unique in cluster)
2393        self.base     = base    # physical base address
2394        self.size     = size    # segment size (bytes)
2395        self.x        = x       # cluster x coordinate
2396        self.y        = y       # cluster y coordinate
2397        self.segtype  = segtype # RAM / PERI (defined in mapping_info.h)
2398
2399        return
2400
2401    ################
2402    def xml( self ):   # xml for a pseg
2403
2404        return '            <pseg name="%s" type="%s" base="0x%x" length="0x%x" />\n' \
2405                % (self.name, self.segtype, self.base, self.size)
2406
2407    ######################################################
2408    def cbin( self, mapping, verbose, expected, cluster ):    # C binary structure for Pseg
2409
2410        if ( verbose ):
2411            print '*** cbin for pseg[%d] %s in cluster[%d,%d]' \
2412                  % (self.index, self.name, cluster.x, cluster.y)
2413
2414        # check index
2415        if (self.index != expected):
2416            print '[genmap error] in Pseg.cbin() : pseg global index = %d / expected = %d' \
2417                  % (self.index, expected )
2418            sys.exit(1)
2419
2420        # compute numerical value for segtype
2421        segtype_int = 0xFFFFFFFF
2422        for x in xrange( len(PSEGTYPES) ):
2423            if ( self.segtype == PSEGTYPES[x] ):
2424                segtype_int = x
2425        if ( segtype_int == 0xFFFFFFFF ):
2426            print '[genmap error] in Pseg.cbin() : undefined segment type %s' % self.segtype
2427            sys.exit(1)
2428
2429        byte_stream = bytearray()
2430        byte_stream += mapping.str2bytes( 32, self.name )      # pseg name
2431        byte_stream += mapping.int2bytes( 8 , self.base )      # physical base address
2432        byte_stream += mapping.int2bytes( 8 , self.size )      # segment length
2433        byte_stream += mapping.int2bytes( 4 , segtype_int )    # segment type
2434        byte_stream += mapping.int2bytes( 4 , cluster.index )  # cluster global index
2435        byte_stream += mapping.int2bytes( 4 , 0 )              # linked list of vsegs
2436
2437        if ( verbose ):
2438            print 'pbase      = %x' %  self.base
2439            print 'size       = %x' %  self.size
2440            print 'type       = %s' %  self.segtype
2441
2442        return byte_stream
2443
2444###########################################################################################
2445class Periph ( object ):
2446###########################################################################################
2447    def __init__( self,
2448                  pseg,               # associated pseg
2449                  ptype,              # peripheral type
2450                  subtype  = 'NONE',  # peripheral subtype
2451                  channels = 1,       # for multi-channels peripherals
2452                  arg      = 0 ):     # optional argument (semantic depends on ptype)
2453
2454        assert ptype in PERIPHTYPES
2455
2456        assert subtype in PERIPHSUBTYPES
2457
2458        self.index    = 0            # global index ( set by addPeriph() )
2459        self.channels = channels
2460        self.ptype    = ptype
2461        self.subtype  = subtype
2462        self.arg      = arg
2463        self.pseg     = pseg
2464        self.irqs     = []
2465        return
2466
2467    ################
2468    def xml( self ):    # xml for a periph
2469
2470        s =  '            <periph type="%s"' % self.ptype
2471        s += ' subtype="%s"'                 % self.subtype
2472        s += ' psegname="%s"'                % self.pseg.name
2473        s += ' channels="%d"'                % self.channels
2474        s += ' arg="%d" >\n'                 % self.arg
2475        if ( (self.ptype == 'PIC') or (self.ptype == 'XCU') ):
2476            for irq in self.irqs: s += irq.xml()
2477        s += '            </periph>\n'
2478
2479        return s
2480
2481    #############################################
2482    def cbin( self, mapping, verbose, expected ):    # C binary structure for Periph
2483
2484        if ( verbose ):
2485            print '*** cbin for periph %s in cluster [%d,%d]' \
2486                  % (self.ptype, self.pseg.x, self.pseg.y)
2487
2488        # check index
2489        if (self.index != expected):
2490            print '[genmap error] in Periph.cbin() : periph global index = %d / expected = %d' \
2491                  % (self.index, expected )
2492            sys.exit(1)
2493
2494        # compute pseg global index
2495        pseg_id = self.pseg.index
2496
2497        # compute first irq global index
2498        if ( len(self.irqs) > 0 ):
2499            irq_id = self.irqs[0].index
2500        else:
2501            irq_id = 0
2502
2503        # compute numerical value for ptype
2504        ptype_id = 0xFFFFFFFF
2505        for x in xrange( len(PERIPHTYPES) ):
2506            if ( self.ptype == PERIPHTYPES[x] ):  ptype_id = x
2507        if ( ptype_id == 0xFFFFFFFF ):
2508            print '[genmap error] in Periph.cbin() : undefined peripheral type %s' % self.ptype
2509            sys.exit(1)
2510
2511        # compute numerical value for subtype
2512        subtype_id = 0xFFFFFFFF
2513        for x in xrange( len(PERIPHSUBTYPES) ):
2514            if ( self.subtype == PERIPHSUBTYPES[x] ):  subtype_id = x
2515
2516        # compute
2517        byte_stream = bytearray()
2518        byte_stream += mapping.int2bytes( 4 , ptype_id )         # peripheral type
2519        byte_stream += mapping.int2bytes( 4 , subtype_id )       # peripheral subtype
2520        byte_stream += mapping.int2bytes( 4 , pseg_id )          # pseg global index
2521        byte_stream += mapping.int2bytes( 4 , self.channels )    # number of channels
2522        byte_stream += mapping.int2bytes( 4 , self.arg )         # optionnal argument
2523        byte_stream += mapping.int2bytes( 4 , len( self.irqs ) ) # number of input irqs
2524        byte_stream += mapping.int2bytes( 4 , irq_id )           # first irq global index
2525
2526        if ( verbose ):
2527            print 'ptype      = %d' %  ptype_id
2528            print 'pseg_id    = %d' %  pseg_id
2529            print 'nb_irqs    = %d' %  len( self.irqs )
2530            print 'irq_id     = %d' %  irq_id
2531        return byte_stream
2532
2533###########################################################################################
2534class Irq ( object ):
2535###########################################################################################
2536    def __init__( self,
2537                  irqtype,         # input IRQ type : HWI / WTI / PTI (for XCU only)
2538                  srcid,           # input IRQ index (for XCU or PIC)
2539                  isrtype,         # Type of ISR to be executed
2540                  channel = 0 ):   # channel index for multi-channel ISR
2541
2542        assert irqtype in IRQTYPES
2543        assert isrtype in ISRTYPES
2544        assert srcid < 32
2545
2546        self.index   = 0        # global index ( set by addIrq() )
2547        self.irqtype = irqtype  # IRQ type
2548        self.srcid   = srcid    # source IRQ index
2549        self.isrtype = isrtype  # ISR type
2550        self.channel = channel  # channel index (for multi-channels ISR)
2551        return
2552
2553    ################
2554    def xml( self ):   # xml for Irq
2555
2556        return '                <irq srctype="%s" srcid="%d" isr="%s" channel="%d" />\n' \
2557                % ( self.irqtype, self.srcid, self.isrtype, self.channel )
2558
2559    #############################################
2560    def cbin( self, mapping, verbose, expected ):     # C binary structure for Irq
2561
2562        if ( verbose ):
2563            print '*** cbin for irq[%d]' % (self.index)
2564
2565        # check index
2566        if (self.index != expected):
2567            print '[genmap error] in Irq.cbin() : irq global index = %d / expected = %d' \
2568                  % (self.index, expected )
2569            sys.exit(1)
2570
2571        # compute numerical value for irqtype
2572        irqtype_id = 0xFFFFFFFF
2573        for x in xrange( len(IRQTYPES) ):
2574            if ( self.irqtype == IRQTYPES[x] ):
2575                irqtype_id = x
2576        if ( irqtype_id == 0xFFFFFFFF ):
2577            print '[genmap error] in Irq.cbin() : undefined irqtype %s' % self.irqtype
2578            sys.exit(1)
2579
2580        # compute numerical value for isrtype
2581        isrtype_id = 0xFFFFFFFF
2582        for x in xrange( len(ISRTYPES) ):
2583            if ( self.isrtype == ISRTYPES[x] ):
2584                isrtype_id = x
2585        if ( isrtype_id == 0xFFFFFFFF ):
2586            print '[genmap error] in Irq.cbin() : undefined isrtype %s' % self.isrtype
2587            sys.exit(1)
2588
2589        byte_stream = bytearray()
2590        byte_stream += mapping.int2bytes( 4,  irqtype_id )
2591        byte_stream += mapping.int2bytes( 4,  self.srcid )
2592        byte_stream += mapping.int2bytes( 4,  isrtype_id )
2593        byte_stream += mapping.int2bytes( 4,  self.channel )
2594        byte_stream += mapping.int2bytes( 4,  0 )
2595        byte_stream += mapping.int2bytes( 4,  0 )
2596
2597        if ( verbose ):
2598            print 'irqtype    = %s' %  self.irqtype
2599            print 'srcid      = %d' %  self.srcid
2600            print 'isrtype    = %s' %  self.isrtype
2601            print 'channel    = %d' %  self.channel
2602
2603        return byte_stream
2604
2605###########################################################################################
2606class Coproc ( object ):
2607###########################################################################################
2608    def __init__( self,
2609                  pseg ):           # associated pseg
2610
2611        self.index    = 0        # global index value set by addCoproc()
2612        self.pseg     = pseg
2613        self.ports    = []
2614
2615        return
2616
2617    ################
2618    def xml( self ):    # xml for Coproc
2619
2620        print '[genmap error] in Coproc.xml() : not defined yet'
2621        sys.exit(1)
2622
2623        return
2624
2625    #############################################
2626    def cbin( self, mapping, verbose, expected ):    # C binary structure for Coproc
2627
2628        if ( verbose ):
2629            print '*** cbin for coproc in cluster (%d,%d)' % (self.pseg.x, self.pseg.y)
2630
2631        # check index
2632        if (self.index != expected):
2633            print '[genmap error] in Coproc.cbin() : coproc global index = %d / expected = %d' \
2634                  % (self.index, expected )
2635            sys.exit(1)
2636
2637        # compute pseg global index
2638        pseg_id = self.pseg.index
2639
2640        # compute first port global index
2641        port_id = self.ports[0].index
2642
2643        byte_stream = bytearray()
2644        byte_stream += mapping.str2bytes( 32, self.pseg.name )    # probablement inutile (AG)
2645        byte_stream += mapping.int2bytes( 4 , pseg_id )           # pseg global index
2646        byte_stream += mapping.int2bytes( 4 , len( self.ports ) ) # number of input irqs
2647        byte_stream += mapping.int2bytes( 4 , port_id )           # first port global index
2648
2649        if ( verbose ):
2650            print 'irqtype    = %s' %  self.irqtype
2651            print 'pseg_id    = %d' %  pseg_id
2652            print 'nb_ports   = %d' %  len( self.ports )
2653            print 'port_id      %d' %  port_id
2654
2655        return byte_stream
2656
2657###########################################################################################
2658class Cpport ( object ):
2659###########################################################################################
2660    def __init__( self,
2661                  direction,
2662                  vspacename,
2663                  mwmrname ):
2664
2665        self.index      = 0           # global index ( set by addCpport() )
2666        self.direction  = direction   # TO_COPROC / FROM_COPROC
2667        self.vspacename = vspacename  # name of vspace containing mwmr channel
2668        self.mwmrname   = mwmrname    # name of vobj defining mwmr channel
2669
2670        return
2671
2672    ################
2673    def xml( self ):    # xml for Cpport
2674
2675        print '[genmap error] in Cpport.xml() : not defined yet'
2676        sys.exit(1)
2677
2678        return
2679
2680    #############################################
2681    def cbin( self, mapping, verbose, expected ):    # C binary structure for Cpport
2682
2683        if ( verbose ):
2684            print '*** cbin for cpport[%d]' % (self.index)
2685
2686        # check index
2687        if ( self.index != expected ):
2688            print '[genmap error] in Cpport.cbin() : port global index = %d / expected = %d' \
2689                  % ( self.index, expected )
2690            sys.exit(1)
2691
2692        # compute numerical value for direction
2693        if ( self.direction == 'TO_COPROC' ):
2694             dir_int = 0
2695        else:
2696             dir_int = 1
2697
2698        # compute vspace global index
2699        vspace_id = 0xFFFFFFFF
2700        for vspace in mapping.vspaces:
2701            if ( self.vspacename == vspace.name ):
2702                vspace_id = vspace.index
2703        if (vspace_id == 0xFFFFFFFF):
2704            print '[genmap error] in Cpport.cbin() : vspace name %s not found' \
2705                  % ( self.vspacename )
2706            sys.exit(1)
2707
2708        # compute mwmr global index
2709        mwmr_id = 0xFFFFFFFF
2710        for vseg in mapping.vspace[vspace_id].vsegs:
2711            for vobj in vseg.vobjs:
2712                if (self.mwmrname == vobj.name):
2713                    mwmr_id = vobj.index
2714        if (mwmr_id == 0xFFFFFFFF):
2715            print '[genmap error] in Cpport.cbin() : mwmr vobj name %s not found in vspace %s' \
2716                  % ( self.mwmrname, self.vspacename )
2717            sys.exit(1)
2718
2719        byte_stream = bytearray()
2720        byte_stream += mapping.int2bytes( 4 , dir_int )         # pseg global index
2721        byte_stream += mapping.int2bytes( 4 , vspace_id )       # vspace global index
2722        byte_stream += mapping.int2bytes( 4 , mwmr_id )         # mwmr vobj global index
2723
2724        if ( verbose ):
2725            print 'direction  = %s' %  self.direction
2726            print 'vspace_id  = %d' %  vspace_id
2727            print 'mwmr_id    = %d' %  mwmr_id
2728
2729        return byte_stream
2730
2731
2732# Local Variables:
2733# tab-width: 4;
2734# c-basic-offset: 4;
2735# c-file-offsets:((innamespace . 0)(inline-open . 0));
2736# indent-tabs-mode: nil;
2737# End:
2738#
2739# vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
2740
Note: See TracBrowser for help on using the repository browser.