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

Last change on this file since 562 was 556, checked in by nicolas.van.phan@…, 6 years ago

Gather LETI-specific macros into hard_config.h

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