source: trunk/tools/arch_info/arch_classes.py @ 74

Last change on this file since 74 was 6, checked in by alain, 7 years ago

Modify the boot_info_t struct to describe external peripherals in all clusters.

File size: 36.9 KB
Line 
1#!/usr/bin/env python
2
3import sys
4
5##########################################################################################
6#  File   : arch_classes.py
7#  Date   : 2016
8#  Author : Alain Greiner
9#  Copyright (c)  UPMC Sorbonne Universites
10#########################################################################################
11#  This file contains the python classes required to define a generic hardware
12#  architecture for the ALMOS-MK operating system.
13#  It handle 4 types of objects: clusters, cores, devices and irqs.
14#  - The number of cluster is variable (can be one).
15#  - The cluster topology can be a 2D mesh or a simple 1D array.
16#  - The number of cores per cluster is variable (can be zero).
17#  - The number of addressable devices per cluster is variable.
18#  - The size of the physical memory bank per cluster is variable.
19#  An adressable device can be a physical memory bank or a peripheral.
20#  Each cluster cover a fixed size segment in physical address space,
21# that is defined by (PADDR_WIDTH - X_WIDTH - Y_WIDTH)
22#########################################################################################
23# Implementation Note:
24# The objects used to describe an architecture are distributed in the python structure:
25# For example the set of cores and the set of devices are split in several subsets
26# (one subset of cores and one subset of devices per cluster).
27# In the generated C binary data structure, all objects of same type
28# are stored in a linear array (one single array for all cores for example).
29# For all objects, we compute and store in the python object  a "global index"
30# corresponding to the index in this global array, and this index can be used as
31# a pseudo-pointer to identify a specific object of a given type.
32#########################################################################################
33
34#########################################################################################
35#  Define global parameters
36#########################################################################################
37
38ARCHINFO_SIGNATURE = 0xBABE2016    # magic number indicating a valid C BLOB
39PAGE_SIZE          = 0x1000        # to check peripherals alignment
40
41#########################################################################################
42# These arrays define the supported types of peripherals.
43# They must be kept consistent with values defined in files arch_info.h & device.h.
44#########################################################################################
45
46DEVICE_TYPES_STR = [
47    'RAM_SCL',         # 0.0
48    'ROM_SCL',         # 1.0
49    'FBF_SCL',         # 2.0
50    'IOB_TSR',         # 3.0
51    'IOC_BDV',         # 4.0
52    'IOC_HBA',         # 4.1
53    'IOC_SDC',         # 4.2
54    'IOC_SPI',         # 4.3
55    'IOC_RDK',         # 4.4
56    'MMC_TSR',         # 5.0
57    'DMA_SCL',         # 6.0
58    'NIC_CBF',         # 7.0
59    'TIM_SCL',         # 8.0
60    'TXT_TTY',         # 9.0
61    'ICU_XCU',         # A.0
62    'PIC_TSR',         # B.0
63    ]
64   
65DEVICE_TYPES_INT = [
66    0x00000000,        # 0.0
67    0x00010000,        # 1.0
68    0x00020000,        # 1.0
69    0x00030000,        # 3.0
70    0x00040000,        # 4.0
71    0x00040001,        # 4.1
72    0x00040002,        # 4.2
73    0x00040003,        # 4.3
74    0x00040004,        # 4.4
75    0x00050000,        # 5.0
76    0x00060000,        # 6.0
77    0x00070000,        # 7.0
78    0x00080000,        # 8.0
79    0x00090000,        # 9.0
80    0x000A0000,        # A.0
81    0x000B0000,        # B.0
82    ]
83
84 #########################################################################################
85class Archinfo( object ):         
86#########################################################################################
87    def __init__( self,
88                  name,              # architecture instance name
89                  x_size,            # number of clusters in a row
90                  y_size,            # number of clusters in a column
91                  cores_max,         # max number of cores per cluster
92                  devices_max,       # max number of devices per cluster
93                  paddr_width,       # number of bits in physical address
94                  x_width,           # number of bits for x coordinate
95                  y_width,           # number of bits for y coordinate
96                  irqs_per_core,     # number or IRQs from ICU to one core
97                  io_cxy,            # IO cluster identifier
98                  boot_cxy,          # boot cluster identifier
99                  cache_line,        # number of bytes in cache line
100                  reset_address,     # Preloader physical base address
101                  p_width ):         # TSAR specific : number of bits to code core lid
102
103        assert ( x_size <= (1<<x_width) )
104        assert ( y_size <= (1<<y_width) )
105
106        self.signature      = ARCHINFO_SIGNATURE
107        self.name           = name
108        self.x_size         = x_size
109        self.y_size         = y_size
110        self.cores_max      = cores_max
111        self.devices_max    = devices_max
112        self.paddr_width    = paddr_width
113        self.x_width        = x_width
114        self.y_width        = y_width
115        self.irqs_per_core  = irqs_per_core
116        self.io_cxy         = io_cxy
117        self.boot_cxy       = boot_cxy
118        self.cache_line     = cache_line
119        self.reset_address  = reset_address
120        self.p_width        = p_width
121
122        self.total_cores    = 0
123        self.total_devices  = 0
124        self.total_irqs     = 0
125
126        self.clusters       = []
127
128        for x in xrange( self.x_size ):
129            for y in xrange( self.y_size ):
130
131                # call cluster constructor
132                cxy = (x<<y_width) + y
133                cluster = Cluster( cxy )
134
135                # update cluster global index
136                cluster.index = (x * self.y_size) + y
137
138                # register cluster in Archinfo
139                self.clusters.append( cluster )
140
141        return
142
143    ##########################   add a device in a cluster
144    def addDevice( self,
145                   ptype,              # device type
146                   base,               # associated pseg base address
147                   size,               # associated pseg length (bytes)
148                   channels = 1,       # number of channels
149                   arg0     = 0,       # optional argument (semantic depends on ptype)
150                   arg1     = 0,       # optional argument (semantic depends on ptype)
151                   arg2     = 0,       # optional argument (semantic depends on ptype)
152                   arg3     = 0 ):     # optional argument (semantic depends on ptype)
153
154        # computes cluster identifier and global index from the base address
155        cxy = base >> (self.paddr_width - self.x_width - self.y_width)
156        x          = cxy >> (self.y_width);
157        y          = cxy & ((1 << self.y_width) - 1)
158        cluster_id = (x * self.y_size) + y
159
160        assert (x < self.x_size) and (y < self.y_size)
161        assert (base & (PAGE_SIZE-1) == 0)
162        assert (ptype in DEVICE_TYPES_STR)
163
164        # call device constructor
165        device = Device( base, size, ptype, channels, arg0, arg1, arg2, arg3 )
166
167        # register device in cluster
168        self.clusters[cluster_id].devices.append( device )
169
170        # update device global index
171        device.index = self.total_devices
172        self.total_devices += 1
173
174        return device
175
176    ################################   add an input IRQ in a device
177    def addIrq( self,
178                dstdev,                # destination device (PIC or ICU)
179                port,                  # input IRQ port index
180                srcdev,                # source device
181                channel = 0,           # source device channel
182                is_rx = False ):       # I/O operation direction
183
184        assert (dstdev.ptype == 'ICU_XCU') or (dstdev.ptype == 'PIC_TSR')
185        assert (port < dstdev.arg0)
186
187        # call Irq constructor
188        irq = Irq( port , srcdev, channel , is_rx )
189
190        # register IRQ in destination device
191        dstdev.irqs.append( irq )
192
193        # update IRQ global index
194        irq.index = self.total_irqs
195        self.total_irqs += 1
196
197        # pointer from the source to the interrupt controller device
198        if (srcdev.irq_ctrl == None): srcdev.irq_ctrl = dstdev
199
200        if (srcdev.irq_ctrl != dstdev):
201            print '[genarch error] in addIrq():'
202            print '    two different interrupt controller for the same device'
203            sys.exit(1)
204
205        return irq
206
207    ##########################    add a core in a cluster
208    def addCore( self,
209                 gid,                  # global hardware identifier
210                 cxy,                  # cluster identifier
211                 lid ):                # local index in cluster
212
213        assert ((cxy >> self.y_width) < self.x_size)
214        assert ((cxy & ((1<<self.y_width)-1)) < self.y_size)
215        assert (lid < self.cores_max)
216 
217        # call Core contructor
218        core = Core( gid, cxy, lid )
219
220        # compute cluster global index from cluster identifier
221        x          = cxy>>self.y_width
222        y          = cxy & ((1<<self.y_width)-1)
223        cluster_id = (x * self.y_size) + y
224
225        # register core in cluster
226        self.clusters[cluster_id].cores.append( core )
227
228        # update core global index
229        core.index = self.total_cores
230        self.total_cores += 1
231
232        return core
233
234    #################################
235    def str2bytes( self, nbytes, s ):    # string => nbytes_packed byte array
236
237        byte_stream = bytearray()
238        length = len( s )
239        if length < (nbytes - 1):
240            for b in s:
241                byte_stream.append( b )
242            for x in xrange(nbytes-length):
243                byte_stream.append( '\0' )
244        else:
245            print '[genarch error] in str2bytes()'
246            print '    string %s too long' % s
247            sys.exit(1)
248
249        return byte_stream
250
251    ###################################
252    def int2bytes( self, nbytes, val ):    # integer => nbytes litle endian byte array
253
254        byte_stream = bytearray()
255        for n in xrange( nbytes ):
256            byte_stream.append( (val >> (n<<3)) & 0xFF )
257
258        return byte_stream
259
260    ################
261    def xml( self ):    # compute string for xml file generation
262
263        s = '<?xml version="1.0"?>\n\n'
264        s += '<arch_info signature    = "0x%x"\n' % (self.signature)
265        s += '           name         = "%s"\n'   % (self.name)
266        s += '           x_size       = "%d"\n'   % (self.x_size)
267        s += '           y_size       = "%d"\n'   % (self.y_size)
268        s += '           cores        = "%d"\n'   % (self.cores_max)
269        s += '           io_cxy       = "%d" >\n' % (self.io_cxy)
270        s += '\n'
271
272        s += '    <clusterset>\n'
273        for x in xrange ( self.x_size ):
274            for y in xrange ( self.y_size ):
275                cluster_id = (x * self.y_size) + y
276                s += self.clusters[cluster_id].xml()
277        s += '    </clusterset>\n'
278        s += '\n'
279
280        s += '</arch_info>\n'
281        return s
282
283    ##########################
284    def cbin( self, verbose ):     # C binary structure for "archinfo.bin" file generation
285
286        byte_stream = bytearray()
287
288        # header
289        byte_stream += self.int2bytes(4,  self.signature)
290        byte_stream += self.int2bytes(4,  self.x_size)
291        byte_stream += self.int2bytes(4,  self.y_size)
292        byte_stream += self.int2bytes(4,  self.paddr_width)
293        byte_stream += self.int2bytes(4,  self.x_width)
294        byte_stream += self.int2bytes(4,  self.y_width)
295        byte_stream += self.int2bytes(4,  self.cores_max)
296        byte_stream += self.int2bytes(4,  self.devices_max)
297
298        byte_stream += self.int2bytes(4,  self.total_cores)
299        byte_stream += self.int2bytes(4,  self.total_devices)
300        byte_stream += self.int2bytes(4,  self.total_irqs)
301        byte_stream += self.int2bytes(4,  self.io_cxy)
302        byte_stream += self.int2bytes(4,  self.boot_cxy)
303        byte_stream += self.int2bytes(4,  self.irqs_per_core)
304        byte_stream += self.int2bytes(4,  self.cache_line)
305        byte_stream += self.int2bytes(4,  0)
306
307        byte_stream += self.str2bytes(64, self.name)
308
309        if ( verbose ):
310            print '\n'
311            print 'name          = %s' % self.name
312            print 'signature     = %x' % self.signature
313            print 'x_size        = %d' % self.x_size
314            print 'y_size        = %d' % self.y_size
315            print 'total_cores   = %d' % self.total_cores
316            print 'total_devices = %d' % self.total_devices
317            print 'total_irqs    = %d' % self.total_irqs
318            print '\n'
319
320        # cores array
321        index = 0
322        for cluster in self.clusters:
323            for core in cluster.cores:
324                byte_stream += core.cbin( self, verbose, index )
325                index += 1
326
327        if ( verbose ): print '\n'
328
329        # clusters array
330        index = 0
331        for cluster in self.clusters:
332            byte_stream += cluster.cbin( self, verbose, index )
333            index += 1
334
335        if ( verbose ): print '\n'
336
337        # devices array
338        index = 0
339        for cluster in self.clusters:
340            for device in cluster.devices:
341                byte_stream += device.cbin( self, verbose, index )
342                index += 1
343
344        if ( verbose ): print '\n'
345
346        # irqs array
347        index = 0
348        for cluster in self.clusters:
349            for device in cluster.devices:
350                for irq in device.irqs:
351                    byte_stream += irq.cbin( self, verbose, index )
352                    index += 1
353
354        if ( verbose ): print '\n'
355
356        return byte_stream
357    # end of cbin()
358
359
360    ######################################################################
361    def hard_config( self ):     # compute string for hard_config.h file
362                                 # required by
363                                 # - top.cpp compilation
364                                 # - almos-mk bootloader compilation
365                                 # - tsar_preloader compilation
366
367        # for each device type, define default values
368        # for pbase address, size, number of components, and channels
369        nb_ram       = 0
370        ram_channels = 0
371        ram_base     = 0xFFFFFFFFFFFFFFFF
372        ram_size     = 0
373
374        nb_rom       = 0
375        rom_channels = 0
376        rom_base     = 0xFFFFFFFFFFFFFFFF
377        rom_size     = 0
378
379        nb_fbf       = 0
380        fbf_channels = 0
381        fbf_base     = 0xFFFFFFFFFFFFFFFF
382        fbf_size     = 0
383        fbf_arg0     = 0
384        fbf_arg1     = 0
385
386        nb_iob       = 0
387        iob_channels = 0
388        iob_base     = 0xFFFFFFFFFFFFFFFF
389        iob_size     = 0
390
391        nb_ioc       = 0
392        ioc_channels = 0
393        ioc_base     = 0xFFFFFFFFFFFFFFFF
394        ioc_size     = 0
395        use_ioc_bdv  = False
396        use_ioc_sdc  = False
397        use_ioc_hba  = False
398        use_ioc_spi  = False
399        use_ioc_rdk  = False
400
401        nb_mmc       = 0
402        mmc_channels = 0
403        mmc_base     = 0xFFFFFFFFFFFFFFFF
404        mmc_size     = 0
405
406        nb_dma       = 0
407        dma_channels = 0
408        dma_base     = 0xFFFFFFFFFFFFFFFF
409        dma_size     = 0
410
411        nb_nic       = 0
412        nic_channels = 0
413        nic_base     = 0xFFFFFFFFFFFFFFFF
414        nic_size     = 0
415
416        nb_sim       = 0
417        sim_channels = 0
418        sim_base     = 0xFFFFFFFFFFFFFFFF
419        sim_size     = 0
420
421        nb_tim       = 0
422        tim_channels = 0
423        tim_base     = 0xFFFFFFFFFFFFFFFF
424        tim_size     = 0
425
426        nb_txt       = 0
427        txt_channels = 0
428        txt_base     = 0xFFFFFFFFFFFFFFFF
429        txt_size     = 0
430
431        nb_icu       = 0
432        icu_channels = 0
433        icu_base     = 0xFFFFFFFFFFFFFFFF
434        icu_size     = 0
435        icu_arg0     = 0
436
437        nb_pic       = 0
438        pic_channels = 0
439        pic_base     = 0xFFFFFFFFFFFFFFFF
440        pic_size     = 0
441
442        nb_rom        = 0
443        rom_channels  = 0
444        rom_base      = 0xFFFFFFFFFFFFFFFF
445        rom_size      = 0
446
447        # get devices attributes
448        for cluster in self.clusters:
449            for device in cluster.devices:
450
451                if ( device.ptype == 'RAM_SCL' ):
452                    ram_base     = device.base
453                    ram_size     = device.size
454                    ram_channels = device.channels
455                    nb_ram +=1
456               
457                elif ( device.ptype == 'ROM_SCL' ):
458                    rom_base     = device.base
459                    rom_size     = device.size
460                    rom_channels = device.channels
461                    nb_rom +=1
462
463                elif ( device.ptype == 'FBF_SCL' ):
464                    fbf_base     = device.base
465                    fbf_size     = device.size
466                    fbf_channels = device.channels
467                    fbf_arg0     = device.arg0
468                    fbf_arg1     = device.arg1
469                    nb_fbf +=1
470
471                elif ( device.ptype == 'IOB_TSR' ):
472                    iob_base     = device.base
473                    iob_size     = device.size
474                    iob_channels = device.channels
475                    nb_iob +=1
476
477                elif ( device.ptype == 'IOC_BDV' ):
478                    ioc_base     = device.base
479                    ioc_size     = device.size
480                    ioc_channels = device.channels
481                    use_ioc_bdv  = True
482                    nb_ioc += 1
483                elif ( device.ptype == 'IOC_HBA' ):
484                    ioc_base     = device.base
485                    ioc_size     = device.size
486                    ioc_channels = device.channels
487                    use_ioc_hba  = True
488                    nb_ioc += 1
489                elif ( device.ptype == 'IOC_SDC' ):
490                    ioc_base     = device.base
491                    ioc_size     = device.size
492                    ioc_channels = device.channels
493                    use_ioc_sdc  = True
494                    nb_ioc += 1
495                elif ( device.ptype == 'IOC_SPI' ):
496                    ioc_base     = device.base
497                    ioc_size     = device.size
498                    ioc_channels = device.channels
499                    use_ioc_spi  = True
500                    nb_ioc += 1
501                elif ( device.ptype == 'IOC_RDK' ):
502                    ioc_base     = device.base
503                    ioc_size     = device.size
504                    ioc_channels = device.channels
505                    use_ioc_rdk  = True
506                    nb_ioc += 1
507
508                elif ( device.ptype == 'MMC_TSR' ):
509                    mmc_base     = device.base
510                    mmc_size     = device.size
511                    mmc_channels = device.channels
512                    nb_mmc +=1
513
514                elif ( device.ptype == 'DMA_SCL' ):
515                    dma_base     = device.base
516                    dma_size     = device.size
517                    dma_channels = device.channels
518                    nb_dma +=1
519
520                elif ( device.ptype == 'NIC_CBF' ):
521                    nic_base     = device.base
522                    nic_size     = device.size
523                    nic_channels = device.channels
524                    nb_nic +=1
525
526                elif ( device.ptype == 'TIM_SCL' ):
527                    tim_base     = device.pseg.base
528                    tim_size     = device.pseg.size
529                    tim_channels = device.channels
530                    nb_tim +=1
531
532                elif ( device.ptype == 'TXT_TTY' ):
533                    txt_base     = device.base
534                    txt_size     = device.size
535                    txt_channels = device.channels
536                    nb_txt +=1
537
538                elif ( device.ptype == 'ICU_XCU' ):
539                    icu_base     = device.base
540                    icu_size     = device.size
541                    icu_channels = device.channels
542                    icu_arg0     = device.arg0
543                    icu_arg1     = device.arg1
544                    icu_arg2     = device.arg2
545                    icu_arg3     = device.arg3
546                    nb_icu +=1
547
548                elif ( device.ptype == 'PIC_TSR' ):
549                    pic_base     = device.base
550                    pic_size     = device.size
551                    pic_channels = device.channels
552                    nb_pic +=1
553
554        # one and only one IOC controller
555        assert ( nb_ioc == 1 )
556
557        # compute rdk_base and rdk_size
558        if( use_ioc_rdk ):
559            rdk_base = ioc_base
560            rdk_size = ioc_size
561        else:
562            rdk_base = 0
563            rdk_size = 0
564
565        # Compute total number of cores, devices and irqs
566        nb_total_cores   = self.total_cores
567        nb_total_devices = self.total_devices
568        nb_total_irqs    = self.total_irqs
569
570        # boot core has (cxy == boot_cxy) and (lid == 0)
571        for cluster in self.clusters:
572            if( cluster.cxy == self.boot_cxy ): boot_core_gid = cluster.cores[0].gid
573
574        # compute mask to get local physical address (cluster independant)
575        local_paddr_width   = self.paddr_width - self.x_width - self.y_width
576        local_physical_mask = (1<<local_paddr_width)-1
577
578        # build string
579        s =  '/* Generated by genarch for %s */\n'  % self.name
580        s += '\n'
581        s += '#ifndef HARD_CONFIG_H\n'
582        s += '#define HARD_CONFIG_H\n'
583        s += '\n'
584
585        s += '/* General platform parameters */\n'
586        s += '\n'
587        s += '#define X_SIZE                 %d\n'    % self.x_size
588        s += '#define Y_SIZE                 %d\n'    % self.y_size
589        s += '#define PADDR_WIDTH            %d\n'    % self.paddr_width
590        s += '#define X_WIDTH                %d\n'    % self.x_width
591        s += '#define Y_WIDTH                %d\n'    % self.y_width
592        s += '#define P_WIDTH                %d\n'    % self.p_width 
593        s += '#define X_IO                   %d\n'    % (self.io_cxy >> self.y_width)
594        s += '#define Y_IO                   %d\n'    % (self.io_cxy & ((1<<self.y_width)-1))
595        s += '#define NB_PROCS_MAX           %d\n'    % self.cores_max
596        s += '#define NB_DEVICES_MAX         %d\n'    % self.devices_max
597        s += '#define IRQ_PER_PROCESSOR      %d\n'    % self.irqs_per_core
598        s += '#define RESET_ADDRESS          0x%x\n'  % self.reset_address
599        s += '#define NB_TOTAL_PROCS         %d\n'    % nb_total_cores
600        s += '#define BOOT_CORE_GID          %d\n'    % boot_core_gid
601        s += '#define BOOT_CORE_CXY          %d\n'    % self.boot_cxy
602        s += '#define CACHE_LINE_SIZE        %d\n'    % self.cache_line
603        s += '\n'
604
605        s += '/* Peripherals */\n'
606        s += '\n'
607        s += '#define NB_TXT_CHANNELS        %d\n'    % txt_channels
608        s += '#define NB_IOC_CHANNELS        %d\n'    % ioc_channels
609        s += '#define NB_NIC_CHANNELS        %d\n'    % nic_channels
610        s += '#define NB_TIM_CHANNELS        %d\n'    % tim_channels
611        s += '\n'
612        s += '#define USE_ICU                %d\n'    % ( nb_icu != 0 )
613        s += '#define USE_IOB                %d\n'    % ( nb_iob != 0 )
614        s += '#define USE_PIC                %d\n'    % ( nb_pic != 0 )
615        s += '#define USE_FBF                %d\n'    % ( nb_fbf != 0 )
616        s += '#define USE_NIC                %d\n'    % ( nb_nic != 0 )
617        s += '#define USE_DMA                %d\n'    % ( nb_dma != 0 )
618        s += '\n'
619        s += '#define USE_IOC_BDV            %d\n'    % use_ioc_bdv
620        s += '#define USE_IOC_SDC            %d\n'    % use_ioc_sdc
621        s += '#define USE_IOC_HBA            %d\n'    % use_ioc_hba
622        s += '#define USE_IOC_SPI            %d\n'    % use_ioc_spi
623        s += '#define USE_IOC_RDK            %d\n'    % use_ioc_rdk
624        s += '\n'
625        s += '#define FBUF_X_SIZE            %d\n'    % fbf_arg0
626        s += '#define FBUF_Y_SIZE            %d\n'    % fbf_arg1
627        s += '\n'
628        s += '#define ICU_NB_HWI             %d\n'    % icu_arg0
629        s += '#define ICU_NB_PTI             %d\n'    % icu_arg1
630        s += '#define ICU_NB_WTI             %d\n'    % icu_arg2
631        s += '#define ICU_NB_OUT             %d\n'    % icu_arg3
632        s += '\n'
633
634        s += '/* local physical base address and size for devices */\n'
635        s += '\n'
636        s += '#define SEG_RAM_BASE           0x%x\n'  % (ram_base & local_physical_mask)
637        s += '#define SEG_RAM_SIZE           0x%x\n'  % ram_size
638        s += '\n'
639        s += '#define SEG_FBF_BASE           0x%x\n'  % (fbf_base & local_physical_mask)
640        s += '#define SEG_FBF_SIZE           0x%x\n'  % fbf_size
641        s += '\n'
642        s += '#define SEG_IOB_BASE           0x%x\n'  % (iob_base & local_physical_mask)
643        s += '#define SEG_IOB_SIZE           0x%x\n'  % iob_size
644        s += '\n'
645        s += '#define SEG_IOC_BASE           0x%x\n'  % (ioc_base & local_physical_mask)
646        s += '#define SEG_IOC_SIZE           0x%x\n'  % ioc_size
647        s += '\n'
648        s += '#define SEG_MMC_BASE           0x%x\n'  % (mmc_base & local_physical_mask)
649        s += '#define SEG_MMC_SIZE           0x%x\n'  % mmc_size
650        s += '\n'
651        s += '#define SEG_DMA_BASE           0x%x\n'  % (dma_base & local_physical_mask)
652        s += '#define SEG_DMA_SIZE           0x%x\n'  % dma_size
653        s += '\n'
654        s += '#define SEG_ROM_BASE           0x%x\n'  % (rom_base & local_physical_mask)
655        s += '#define SEG_ROM_SIZE           0x%x\n'  % rom_size
656        s += '\n'
657        s += '#define SEG_SIM_BASE           0x%x\n'  % (sim_base & local_physical_mask)
658        s += '#define SEG_SIM_SIZE           0x%x\n'  % sim_size
659        s += '\n'
660        s += '#define SEG_NIC_BASE           0x%x\n'  % (nic_base & local_physical_mask)
661        s += '#define SEG_NIC_SIZE           0x%x\n'  % nic_size
662        s += '\n'
663        s += '#define SEG_PIC_BASE           0x%x\n'  % (pic_base & local_physical_mask)
664        s += '#define SEG_PIC_SIZE           0x%x\n'  % pic_size
665        s += '\n'
666        s += '#define SEG_TIM_BASE           0x%x\n'  % (tim_base & local_physical_mask)
667        s += '#define SEG_TIM_SIZE           0x%x\n'  % tim_size
668        s += '\n'
669        s += '#define SEG_TXT_BASE           0x%x\n'  % (txt_base & local_physical_mask)
670        s += '#define SEG_TXT_SIZE           0x%x\n'  % txt_size
671        s += '\n'
672        s += '#define SEG_ICU_BASE           0x%x\n'  % (icu_base & local_physical_mask)
673        s += '#define SEG_ICU_SIZE           0x%x\n'  % icu_size
674        s += '\n'
675        s += '#define SEG_RDK_BASE           0x%x\n'  % (rdk_base & local_physical_mask)
676        s += '#define SEG_RDK_SIZE           0x%x\n'  % rdk_size
677        s += '\n'
678        s += '#endif\n'
679
680        return s
681
682    # end of hard_config()
683
684
685
686
687
688###################################################################################
689class Cluster ( object ):
690###################################################################################
691    def __init__( self,
692                  cxy ):
693
694        self.index       = 0           # global index (set by Archinfo constructor)
695        self.cxy         = cxy         # cluster identifier
696        self.cores       = []          # local cores (filled by addCore)
697        self.devices     = []          # local devices(filled by addDevice)
698
699        return
700
701    ################
702    def xml( self ):  # xml for a cluster
703
704        s = '        <cluster cxy = "%x" >\n' % (self.cxy)
705        for core   in self.cores:   s += core.xml()
706        for device in self.devices: s += device.xml()
707        s += '        </cluster>\n'
708
709        return s
710
711    #############################################
712    def cbin( self, mapping, verbose, expected ):  # C binary structure for Cluster
713
714        if ( verbose ):
715            print '*** cbin for cluster[%d] / identifier = %x' \
716                   % (self.index , self.cxy)
717
718        # check index
719        if (self.index != expected):
720            print '[genarch error] in Cluster.cbin()'
721            print '    cluster global index = %d / expected = %d' \
722                       % (self.index,expected)
723            sys.exit(1)
724
725        # compute global index for first core in cluster
726        if ( len(self.cores) > 0 ):
727            core_id = self.cores[0].index
728        else:
729            core_id = 0
730
731        # compute global index for first device in cluster
732        if ( len(self.devices) > 0 ):
733            device_id = self.devices[0].index
734        else:
735            device_id = 0
736
737        byte_stream = bytearray()
738        byte_stream += mapping.int2bytes(4,self.cxy)          # cxy
739        byte_stream += mapping.int2bytes(4,len(self.cores))   # cores in cluster
740        byte_stream += mapping.int2bytes(4,core_id )          # first core global index
741        byte_stream += mapping.int2bytes(4,len(self.devices)) # devices in cluster
742        byte_stream += mapping.int2bytes(4, device_id )       # first device global index
743
744        if ( verbose ):
745            print 'nb_cores   = %d' %  len( self.cores )
746            print 'core_id    = %d' %  core_id
747            print 'nb_devices = %d' %  len( self.devices )
748            print 'device_id  = %d' %  device_id
749
750        return byte_stream
751
752
753
754
755##################################################################################
756class Core ( object ):         
757##################################################################################
758    def __init__( self,
759                  gid,
760                  cxy,
761                  lid ):
762
763        self.index    = 0          # global index / set by addProc()
764        self.gid      = gid        # hardware identifier
765        self.cxy      = cxy        # cluster identifier
766        self.lid      = lid        # local index in cluster
767
768        return
769
770    ###################################
771    def xml( self ):   # xml for a core
772        return '            <core gid="%x" lid="%d" />\n' % (self.gid, self.lid)
773
774    ####################################################################
775    def cbin( self, mapping, verbose, expected ):    # C binary for Proc
776
777        if ( verbose ):
778            print '*** cbin for core [%d] in cluster %x' \
779                  % (self.lid, self.cxy)
780
781        # check index
782        if (self.index != expected):
783            print '[genarch error] in Core.cbin()'
784            print '    core global index = %d / expected = %d' \
785                       % (self.index,expected)
786            sys.exit(1)
787
788        byte_stream = bytearray()
789        byte_stream += mapping.int2bytes( 4 , self.gid )      # hardware identifier
790        byte_stream += mapping.int2bytes( 2 , self.cxy )      # cluster identifier
791        byte_stream += mapping.int2bytes( 2 , self.lid )      # local index
792
793        return byte_stream
794
795
796
797
798##################################################################################
799class Device ( object ):
800##################################################################################
801    def __init__( self,
802                  base,
803                  size,
804                  ptype,
805                  channels = 1,
806                  arg0     = 0,
807                  arg1     = 0,
808                  arg2     = 0,
809                  arg3     = 0 ):
810
811        self.index    = 0             # global device index ( set by addDevice() )
812        self.base     = base          # associated segment base
813        self.size     = size          # associated segment size (bytes)
814        self.ptype    = ptype         # device type
815        self.channels = channels      # number of channels
816        self.arg0     = arg0          # optional (semantic depends on ptype)
817        self.arg1     = arg1          # optional (semantic depends on ptype)
818        self.arg2     = arg2          # optional (semantic depends on ptype)
819        self.arg3     = arg3          # optional (semantic depends on ptype)
820        self.irqs     = []            # set of input IRQs (for PIC and ICU only)
821        self.irq_ctrl = None          # interrupt controller for this device
822        return
823
824    ######################################
825    def xml( self ):    # xml for a device
826
827        s =  '            <device type="%s"' % self.ptype
828        s += ' base="%x"'                    % self.base
829        s += ' size="%x"'                    % self.size
830        s += ' channels="%d"'                % self.channels
831        s += ' arg0="%d"'                    % self.arg0
832        s += ' arg1="%d"'                    % self.arg1
833        s += ' arg2="%d"'                    % self.arg2
834        s += ' arg3="%d"'                    % self.arg3
835        if ( (self.ptype == 'PIC_TSR') or (self.ptype == 'ICU_XCU') ):
836            s += ' >\n'
837            for irq in self.irqs: s += irq.xml()
838            s += '            </device>\n'
839        else:
840            s += ' />\n'
841        return s
842
843    ######################################################################
844    def cbin( self, mapping, verbose, expected ):    # C binary for Periph
845
846        if ( verbose ):
847            print '*** cbin for device[%d] / type = %s / base = %x' \
848                  % (self.index , self.ptype , self.base)
849
850        # check index
851        if (self.index != expected):
852            print '[genarch error] in Periph.cbin()'
853            print '    device global index = %d / expected = %d' \
854                       % (self.index,expected)
855            sys.exit(1)
856
857        # compute first irq global index
858        if ( len(self.irqs) > 0 ):
859            irq_id = self.irqs[0].index
860        else:
861            irq_id = 0
862
863        # compute device type numerical value
864        ptype_id = 0xFFFFFFFF
865        for x in xrange( len(DEVICE_TYPES_STR) ):
866            if ( self.ptype == DEVICE_TYPES_STR[x] ):  ptype_id = DEVICE_TYPES_INT[x]
867
868        if ( ptype_id == 0xFFFFFFFF ):
869            print '[genarch error] in Device.cbin()'
870            print '    undefined device type %s' % self.ptype
871            sys.exit(1)
872
873        byte_stream = bytearray()
874        byte_stream += mapping.int2bytes(8,self.base)      # segment base address
875        byte_stream += mapping.int2bytes(8,self.size)      # segment size
876        byte_stream += mapping.int2bytes(4,ptype_id)       # device type
877        byte_stream += mapping.int2bytes(4,self.channels)  # number of channels
878        byte_stream += mapping.int2bytes(4,self.arg0)      # optionnal arg0
879        byte_stream += mapping.int2bytes(4,self.arg1)      # optionnal arg1
880        byte_stream += mapping.int2bytes(4,self.arg2)      # optionnal arg2
881        byte_stream += mapping.int2bytes(4,self.arg3)      # optionnal arg3
882        byte_stream += mapping.int2bytes(4,len(self.irqs)) # number of input irqs
883        byte_stream += mapping.int2bytes(4 ,irq_id)        # first irq global index
884
885        if ( verbose ):
886            print 'base       = %x' %  self.base
887            print 'size       = %x' %  self.size
888            print 'nb_irqs    = %d' %  len( self.irqs )
889            print 'irq_id     = %d' %  irq_id
890
891        return byte_stream
892
893##################################################################################
894class Irq ( object ): 
895##################################################################################
896    def __init__( self,
897                  port,
898                  dev,
899                  channel,
900                  is_rx ): 
901
902        assert port < 32
903
904        self.index   = 0              # global index ( set by addIrq() )
905        self.port    = port           # input IRQ port index
906        self.dev     = dev            # source device
907        self.channel = channel        # source device channel
908        self.is_rx   = is_rx          # source device direction
909
910        return
911
912    ################################
913    def xml( self ):   # xml for Irq
914        s = '                <irq port="%d" devtype="%s" channel="%d" is_rx="%d" />\n' \
915                             % ( self.port, self.dev.ptype, self.channel, self.is_rx )
916        return s
917
918    ####################################################################
919    def cbin( self, mapping, verbose, expected ):     # C binary for Irq
920
921        if ( verbose ):
922            print '*** cbin for irq[%d] / src_dev = %s' \
923                   % (self.port , self.dev.ptype)
924
925        # check index
926        if (self.index != expected):
927            print '[genarch error] in Irq.cbin()'
928            print '    irq global index = %d / expected = %d' \
929                       % (self.index , expected)
930            sys.exit(1)
931
932        # compute source device type numerical value
933        dev_id = 0xFFFFFFFF
934        for x in xrange( len(DEVICE_TYPES_STR) ):
935            if ( self.dev.ptype == DEVICE_TYPES_STR[x] ): dev_id = DEVICE_TYPES_INT[x]
936
937        if ( dev_id == 0xFFFFFFFF ):
938            print '[genarch error] in Irq.cbin()'
939            print '    undefined device type %s' % self.dev.ptype
940            sys.exit(1)
941
942        byte_stream = bytearray()
943        byte_stream += mapping.int2bytes( 4,  dev_id )
944        byte_stream += mapping.int2bytes( 1,  self.channel )
945        byte_stream += mapping.int2bytes( 1,  self.is_rx )
946        byte_stream += mapping.int2bytes( 1,  self.port )
947        byte_stream += mapping.int2bytes( 1,  0 )
948
949        if ( verbose ):
950            print 'dev_id     = %d' %  dev_id
951            print 'channel    = %d' %  self.channel
952            print 'is_rx      = %d' %  self.is_rx   
953            print 'port       = %s' %  self.port
954
955        return byte_stream
956
957# Local Variables:
958# tab-width: 4;
959# c-basic-offset: 4;
960# c-file-offsets:((innamespace . 0)(inline-open . 0));
961# indent-tabs-mode: nil;
962# End:
963#
964# vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
965
Note: See TracBrowser for help on using the repository browser.