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

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

Removing support for the (use_tty, use_tim, use_nic, use_cma) constructs in the mapping.
Introducing the "display" application using the CMA component to acces the frame buffer.

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