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

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

Introduce the "active" field in vspace.
When this field is set the application is directly started by the kernel_init.

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