source: trunk/platforms/tsar_generic_iob/arch.py @ 1000

Last change on this file since 1000 was 979, checked in by alain, 10 years ago

The mmc variable corresponding to the MMC peripheral must be defined
To support the new addIrq() prototype.

  • Property svn:executable set to *
File size: 20.2 KB
RevLine 
[938]1#!/usr/bin/env python
[707]2
[802]3from math import log, ceil
[707]4from mapping import *
5
[938]6##################################################################################
[714]7#   file   : arch.py  (for the tsar_generic_iob architecture)
[707]8#   date   : may 2014
9#   author : Alain Greiner
[938]10##################################################################################
[802]11#  This file contains a mapping generator for the "tsar_generic_iob" platform.
[707]12#  This includes both the hardware architecture (clusters, processors, peripherals,
[938]13#  physical space segmentation) and the mapping of all boot and kernel objects
14#  (global vsegs).
[714]15#
[966]16#  This platform includes 7 external peripherals, accessible through an IOB
[938]17#  components located in cluster [0,0] or in cluster [x_size-1, y_size-1].
[966]18#  Available peripherals are: TTY, IOC, FBF, ROM, NIC, CMA, PIC.
[938]19#
20#  All clusters contain (nb_procs) processors, one L2 cache, one XCU, and
[972]21#  one optional hardware coprocessor connected to a MWMR_DMA controller.
[938]22#
[966]23#  The "constructor" parameters (defined in Makefile) are:
[714]24#  - x_size         : number of clusters in a row
25#  - y_size         : number of clusters in a column
26#  - nb_procs       : number of processors per cluster
[874]27#  - nb_ttys        : number of TTY channels
[817]28#  - fbf_width      : frame_buffer width = frame_buffer heigth
[972]29#  - ioc_type       : can be 'BDV','HBA','SDC', but not 'RDK'
30#   
[714]31#
[972]32#  The other hardware parameters (defined in this script) are:
[714]33#  - nb_nics        : number of NIC channels
[938]34#  - nb_cmas        : number of CMA channels
[714]35#  - x_io           : cluster_io x coordinate
36#  - y_io           : cluster_io y coordinate
37#  - x_width        : number of bits for x coordinate
38#  - y_width        : number of bits for y coordinate
39#  - paddr_width    : number of bits for physical address
40#  - irq_per_proc   : number of input IRQs per processor
41#  - use_ramdisk    : use a ramdisk when True
[966]42#  - vseg_increment : address increment for replicated vsegs
[972]43#  - mwr_type       : coprocessor type / can be 'GCD','DCT','NOPE'
44#  - use_dma        : one single channel DMA per cluster if non zero
[817]45#
[938]46#  Regarding the boot and kernel vsegs mapping :
47#  - We use one big physical page (2 Mbytes) for the preloader and the four
48#    boot vsegs, all allocated in cluster[0,0].
49#  - We use one big page per cluster for the replicated kernel code vsegs.
50#  - We use one big page in cluster[0][0] for the kernel data vseg.
51#  - We use one big page per cluster for the distributed kernel heap vsegs.
52#  - We use one big page per cluster for the distributed ptab vsegs.
53#  - We use small physical pages (4 Kbytes) per cluster for the schedulers.
54#  - We use one big page for each external peripheral in IO cluster,
55#  - We use one small page per cluster for each internal peripheral.
56##################################################################################
[707]57
[714]58########################
59def arch( x_size    = 2,
60          y_size    = 2,
[817]61          nb_procs  = 2,
[874]62          nb_ttys   = 1,
[965]63          fbf_width = 128,
[972]64          ioc_type  = 'HBA' ):
[714]65
66    ### define architecture constants
67
[913]68    nb_nics         = 1 
69    nb_cmas         = 2
[817]70    x_io            = 0
71    y_io            = 0
72    x_width         = 4
73    y_width         = 4
74    p_width         = 4
75    paddr_width     = 40
[972]76    irq_per_proc    = 4         
[966]77    peri_increment  = 0x10000 
[979]78    mwr_type        = 'GCD'
[802]79
[972]80    ### constructor parameters checking
[714]81
[802]82    assert( nb_procs <= (1 << p_width) )
[707]83
[802]84    assert( (x_size == 1) or (x_size == 2) or (x_size == 4)
[764]85             or (x_size == 8) or (x_size == 16) )
[707]86
[802]87    assert( (y_size == 1) or (y_size == 2) or (y_size == 4)
[707]88             or (y_size == 8) or (y_size == 16) )
89
[943]90    assert( (nb_ttys >= 1) and (nb_ttys <= 8) )
[707]91
92    assert( ((x_io == 0) and (y_io == 0)) or
93            ((x_io == x_size-1) and (y_io == y_size-1)) )
94
[966]95    assert( ioc_type in [ 'BDV' , 'HBA' , 'SDC' ] )
[972]96
97    assert( mwr_type in [ 'GCD' , 'DCT' , 'CPY' , 'NONE' ] )
[965]98 
99    ### define platform name
[802]100
[965]101    platform_name = 'tsar_iob_%d_%d_%d' % ( x_size, y_size , nb_procs )
102    platform_name += '_%d_%d_%s' % ( fbf_width , nb_ttys , ioc_type )
[707]103
[938]104    ### define physical segments replicated in all clusters
105
[707]106    ram_base = 0x0000000000
[913]107    ram_size = 0x1000000                   # 16 Mbytes
[707]108
[802]109    xcu_base = 0x00B0000000
110    xcu_size = 0x1000                      # 4 Kbytes
[707]111
[972]112    mwr_base = 0x00B1000000
113    mwr_size = 0x1000                      # 4 Kbytes
[707]114
[802]115    mmc_base = 0x00B2000000
[714]116    mmc_size = 0x1000                      # 4 Kbytes
[707]117
[817]118    ### define physical segments for external peripherals
119    ## These segments are only defined in cluster_io
120
[965]121    ioc_base  = 0x00B3000000
122    ioc_size  = 0x1000                     # 4 Kbytes
[707]123
[945]124    tty_base  = 0x00B4000000
[714]125    tty_size  = 0x4000                     # 16 Kbytes
[707]126
[945]127    nic_base  = 0x00B5000000
[714]128    nic_size  = 0x80000                    # 512 kbytes
[707]129
[945]130    cma_base  = 0x00B6000000
[714]131    cma_size  = 0x1000 * 2 * nb_nics       # 4 kbytes * 2 * nb_nics
[707]132
[945]133    fbf_base  = 0x00B7000000
[874]134    fbf_size  = fbf_width * fbf_width     # fbf_width * fbf_width bytes
[707]135
[945]136    pic_base  = 0x00B8000000
[714]137    pic_size  = 0x1000                     # 4 Kbytes
[707]138
[945]139    iob_base  = 0x00BE000000
[817]140    iob_size  = 0x1000                     # 4 bytes
[707]141
[945]142    rom_base  = 0x00BFC00000
[714]143    rom_size  = 0x4000                     # 16 Kbytes
[707]144
[754]145    ### define  bootloader vsegs base addresses and sizes
[817]146    ### We want to pack these 4 vsegs in the same big page
[913]147    ### => boot cost is one BIG page in cluster[0][0]
[707]148
[913]149    boot_mapping_vbase   = 0x00000000           # ident
150    boot_mapping_size    = 0x00080000           # 512 Kbytes
[707]151
[913]152    boot_code_vbase      = 0x00080000           # ident
153    boot_code_size       = 0x00040000           # 256 Kbytes
[802]154
[913]155    boot_data_vbase      = 0x000C0000           # ident
156    boot_data_size       = 0x000C0000           # 768 Kbytes
[707]157
[913]158    boot_stack_vbase     = 0x00180000           # ident
159    boot_stack_size      = 0x00080000           # 512 Kbytes
[707]160
[754]161    ### define kernel vsegs base addresses and sizes
[913]162    ### code, init, ptab, heap & sched vsegs are replicated in all clusters.
[817]163    ### data & uncdata vsegs are only mapped in cluster[0][0].
[707]164
[802]165    kernel_code_vbase    = 0x80000000
[913]166    kernel_code_size     = 0x00100000           # 1 Mbytes per cluster
[707]167
[913]168    kernel_init_vbase    = 0x80100000
169    kernel_init_size     = 0x00100000           # 1 Mbytes per cluster
[707]170
[913]171    kernel_data_vbase    = 0x90000000
172    kernel_data_size     = 0x00200000           # 2 Mbytes in cluster[0,0]
[707]173
[817]174    kernel_ptab_vbase    = 0xE0000000
[913]175    kernel_ptab_size     = 0x00200000           # 2 Mbytes per cluster
[707]176
[913]177    kernel_heap_vbase    = 0xD0000000
178    kernel_heap_size     = 0x00200000           # 2 Mbytes per cluster
[707]179
[817]180    kernel_sched_vbase   = 0xA0000000   
181    kernel_sched_size    = 0x00002000*nb_procs  # 8 Kbytes per proc per cluster
182
[938]183    #########################
[707]184    ### create mapping
[938]185    #########################
[707]186
[817]187    mapping = Mapping( name           = platform_name, 
188                       x_size         = x_size,       
189                       y_size         = y_size,       
190                       nprocs         = nb_procs,     
191                       x_width        = x_width,       
192                       y_width        = y_width,       
[802]193                       p_width        = p_width,
[817]194                       paddr_width    = paddr_width,   
195                       coherence      = True,         
196                       irq_per_proc   = irq_per_proc, 
[965]197                       use_ramdisk    = (ioc_type == 'RDK'),
[817]198                       x_io           = x_io,         
[714]199                       y_io           = y_io,
[802]200                       peri_increment = peri_increment,
201                       ram_base       = ram_base,
202                       ram_size       = ram_size )
[707]203
204
[938]205    #############################
206    ###   Hardware Components
207    #############################
[707]208
[938]209    for x in xrange( x_size ):
210        for y in xrange( y_size ):
211            cluster_xy = (x << y_width) + y;
212            offset     = cluster_xy << (paddr_width - x_width - y_width)
[707]213
[938]214            ### components replicated in all clusters
[972]215            mapping.addRam( 'RAM', base = ram_base + offset, 
[938]216                                  size = ram_size )
[707]217
[938]218            xcu = mapping.addPeriph( 'XCU', base = xcu_base + offset, 
219                                     size = xcu_size, ptype = 'XCU', 
[955]220                                     channels = nb_procs * irq_per_proc, 
[959]221                                     arg0 = 32, arg1 = 32, arg2 = 32 )
[707]222
[979]223            mmc = mapping.addPeriph( 'MMC', base = mmc_base + offset,
224                                     size = mmc_size, ptype = 'MMC' )
[707]225
[972]226            if ( mwr_type == 'GCD' ):
[975]227                mwr = mapping.addPeriph( 'MWR', base = mwr_base + offset,
228                                         size = mwr_size, ptype = 'MWR', subtype = 'GCD',
229                                         arg0 = 2, arg1 = 1, arg2 = 1, arg3 = 0 )
[972]230
231            if ( mwr_type == 'DCT' ):
[975]232                mwr = mapping.addPeriph( 'MWR', base = mwr_base + offset,
233                                         size = mwr_size, ptype = 'MWR', subtype = 'DCT',
234                                         arg0 = 1, arg1 = 1, arg2 = 1, arg3 = 0 )
[972]235
236            if ( mwr_type == 'CPY' ):
[975]237                mwr = mapping.addPeriph( 'MWR', base = mwr_base + offset,
238                                         size = mwr_size, ptype = 'MWR', subtype = 'CPY',
239                                         arg0 = 1, arg1 = 1, arg2 = 1, arg3 = 0 )
[972]240
[975]241            mapping.addIrq( xcu, index = 0, src = mmc, isrtype = 'ISR_MMC' )
242            mapping.addIrq( xcu, index = 1, src = mwr, isrtype = 'ISR_MWR' )
243
[938]244            for p in xrange ( nb_procs ):
[972]245                mapping.addProc( x , y , p )
[707]246
[938]247            ### external peripherals in cluster_io
248            if ( (x==x_io) and (y==y_io) ):
[707]249
[945]250                iob = mapping.addPeriph( 'IOB', base = iob_base + offset, size = iob_size, 
[938]251                                         ptype = 'IOB' )
[707]252
[965]253                ioc = mapping.addPeriph( 'IOC', base = ioc_base + offset, size = ioc_size, 
254                                         ptype = 'IOC', subtype = ioc_type )
[707]255
[945]256                tty = mapping.addPeriph( 'TTY', base = tty_base + offset, size = tty_size, 
[938]257                                         ptype = 'TTY', channels = nb_ttys )
[710]258
[945]259                nic = mapping.addPeriph( 'NIC', base = nic_base + offset, size = nic_size, 
[938]260                                         ptype = 'NIC', channels = nb_nics )
[707]261
[945]262                cma = mapping.addPeriph( 'CMA', base = cma_base + offset, size = cma_size, 
[938]263                                         ptype = 'CMA', channels = nb_cmas )
[707]264
[945]265                fbf = mapping.addPeriph( 'FBF', base = fbf_base + offset, size = fbf_size, 
[955]266                                         ptype = 'FBF', arg0 = fbf_width, arg1 = fbf_width )
[707]267
[945]268                rom = mapping.addPeriph( 'ROM', base = rom_base + offset, size = rom_size, 
[938]269                                         ptype = 'ROM' )
[707]270
[945]271                pic = mapping.addPeriph( 'PIC', base = pic_base + offset, size = pic_size, 
[938]272                                         ptype = 'PIC', channels = 32 )
[707]273
[975]274                mapping.addIrq( pic, index = 0, src = nic,
275                                isrtype = 'ISR_NIC_RX', channel = 0 )
276                mapping.addIrq( pic, index = 1, src = nic,
277                                isrtype = 'ISR_NIC_RX', channel = 1 )
[707]278
[975]279                mapping.addIrq( pic, index = 2, src = nic,
280                                isrtype = 'ISR_NIC_TX', channel = 0 )
281                mapping.addIrq( pic, index = 3, src = nic,
282                                isrtype = 'ISR_NIC_TX', channel = 1 )
[710]283
[975]284                mapping.addIrq( pic, index = 4, src = cma,
285                                isrtype = 'ISR_CMA', channel = 0 )
286                mapping.addIrq( pic, index = 5, src = cma,
287                                isrtype = 'ISR_CMA', channel = 1 )
288                mapping.addIrq( pic, index = 6, src = cma,
289                                isrtype = 'ISR_CMA', channel = 2 )
290                mapping.addIrq( pic, index = 7, src = cma,
291                                isrtype = 'ISR_CMA', channel = 3 )
[770]292
[965]293                if ( ioc_type == 'BDV' ): isr_ioc = 'ISR_BDV'
294                if ( ioc_type == 'HBA' ): isr_ioc = 'ISR_HBA'
295                if ( ioc_type == 'SDC' ): isr_ioc = 'ISR_SDC'
[707]296
[975]297                mapping.addIrq( pic, index = 8, src = ioc,
298                                isrtype = isr_ioc, channel = 0 )
299                mapping.addIrq( pic, index = 16, src = tty,
300                                isrtype = 'ISR_TTY_RX', channel = 0 )
301                mapping.addIrq( pic, index = 17, src = tty,
302                                isrtype = 'ISR_TTY_RX', channel = 1 )
303                mapping.addIrq( pic, index = 18, src = tty,
304                                isrtype = 'ISR_TTY_RX', channel = 2 )
305                mapping.addIrq( pic, index = 19, src = tty,
306                                isrtype = 'ISR_TTY_RX', channel = 3 )
307                mapping.addIrq( pic, index = 20, src = tty,
308                                isrtype = 'ISR_TTY_RX', channel = 4 )
309                mapping.addIrq( pic, index = 21, src = tty,
310                                isrtype = 'ISR_TTY_RX', channel = 5 )
311                mapping.addIrq( pic, index = 22, src = tty,
312                                isrtype = 'ISR_TTY_RX', channel = 6 )
313                mapping.addIrq( pic, index = 23, src = tty,
314                                isrtype = 'ISR_TTY_RX', channel = 7 )
[965]315
[938]316
317    ####################################
318    ###   Boot & Kernel vsegs mapping
319    ####################################
320
[817]321    ### global vsegs for boot_loader
322    ### we want to pack those 4 vsegs in the same big page
323    ### => same flags CXW_ / identity mapping / non local / big page
[707]324
[730]325    mapping.addGlobal( 'seg_boot_mapping', boot_mapping_vbase, boot_mapping_size,
[817]326                       'CXW_', vtype = 'BLOB'  , x = 0, y = 0, pseg = 'RAM',
327                       identity = True , local = False, big = True )
[707]328
[730]329    mapping.addGlobal( 'seg_boot_code', boot_code_vbase, boot_code_size,
330                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
[817]331                       identity = True , local = False, big = True )
[707]332
[730]333    mapping.addGlobal( 'seg_boot_data', boot_data_vbase, boot_data_size,
[817]334                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
335                       identity = True , local = False, big = True )
[707]336
[730]337    mapping.addGlobal( 'seg_boot_stack', boot_stack_vbase, boot_stack_size,
[817]338                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
339                       identity = True , local = False, big = True )
[707]340
[943]341    ### global vseg kernel_data : big / non local
342    ### Only mapped in cluster[0][0]
343    mapping.addGlobal( 'seg_kernel_data', kernel_data_vbase, kernel_data_size, 
344                       'CXW_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM', 
345                       binpath = 'build/kernel/kernel.elf', 
346                       local = False, big = True )
347
[913]348    ### global vsegs kernel_code, kernel_init : big / local
[965]349    ### replicated in all clusters with indexed name & same vbase
[874]350    for x in xrange( x_size ):
351        for y in xrange( y_size ):
[965]352            mapping.addGlobal( 'seg_kernel_code_%d_%d' %(x,y), 
353                               kernel_code_vbase, kernel_code_size,
[817]354                               'CXW_', vtype = 'ELF', x = x , y = y , pseg = 'RAM',
355                               binpath = 'build/kernel/kernel.elf', 
356                               local = True, big = True )
[707]357
[965]358            mapping.addGlobal( 'seg_kernel_init_%d_%d' %(x,y), 
359                               kernel_init_vbase, kernel_init_size,
[817]360                               'CXW_', vtype = 'ELF', x = x , y = y , pseg = 'RAM',
361                               binpath = 'build/kernel/kernel.elf', 
362                               local = True, big = True )
[707]363
[938]364    ### Global vsegs kernel_ptab_x_y : big / non local
365    ### one vseg per cluster: name indexed by (x,y)
366    for x in xrange( x_size ):
367        for y in xrange( y_size ):
368            offset = ((x << y_width) + y) * kernel_ptab_size
369            base   = kernel_ptab_vbase + offset
370            mapping.addGlobal( 'seg_kernel_ptab_%d_%d' %(x,y), base, kernel_ptab_size,
371                               'CXW_', vtype = 'PTAB', x = x, y = y, pseg = 'RAM', 
372                               local = False , big = True )
373
[913]374    ### global vsegs kernel_sched_x_y : small / non local
[874]375    ### one vseg per cluster with name indexed by (x,y)
[817]376    for x in xrange( x_size ):
377        for y in xrange( y_size ):
[913]378            offset = ((x << y_width) + y) * kernel_sched_size
[938]379            mapping.addGlobal( 'seg_kernel_sched_%d_%d' %(x,y), 
380                               kernel_sched_vbase + offset , kernel_sched_size,
[817]381                               'C_W_', vtype = 'SCHED', x = x , y = y , pseg = 'RAM',
382                               local = False, big = False )
[707]383
[913]384    ### global vsegs kernel_heap_x_y : big / non local
385    ### one vseg per cluster with name indexed by (x,y)
386    for x in xrange( x_size ):
387        for y in xrange( y_size ):
388            offset = ((x << y_width) + y) * kernel_heap_size
[938]389            mapping.addGlobal( 'seg_kernel_heap_%d_%d' %(x,y), 
390                               kernel_heap_vbase + offset , kernel_heap_size,
[913]391                               'C_W_', vtype = 'HEAP', x = x , y = y , pseg = 'RAM',
392                               local = False, big = True )
393
[817]394    ### global vsegs for external peripherals : non local / big page
[802]395    mapping.addGlobal( 'seg_iob', iob_base, iob_size, '__W_',
396                       vtype = 'PERI', x = 0, y = 0, pseg = 'IOB',
[817]397                       local = False, big = True )
[707]398
[965]399    mapping.addGlobal( 'seg_ioc', ioc_base, ioc_size, '__W_',
400                       vtype = 'PERI', x = 0, y = 0, pseg = 'IOC',
[817]401                       local = False, big = True )
[707]402
[802]403    mapping.addGlobal( 'seg_tty', tty_base, tty_size, '__W_',
[730]404                       vtype = 'PERI', x = 0, y = 0, pseg = 'TTY',
[817]405                       local = False, big = True )
[707]406
[802]407    mapping.addGlobal( 'seg_nic', nic_base, nic_size, '__W_',
[730]408                       vtype = 'PERI', x = 0, y = 0, pseg = 'NIC',
[817]409                       local = False, big = True )
[707]410
[802]411    mapping.addGlobal( 'seg_cma', cma_base, cma_size, '__W_',
[730]412                       vtype = 'PERI', x = 0, y = 0, pseg = 'CMA',
[817]413                       local = False, big = True )
[707]414
[802]415    mapping.addGlobal( 'seg_fbf', fbf_base, fbf_size, '__W_',
[730]416                       vtype = 'PERI', x = 0, y = 0, pseg = 'FBF',
[817]417                       local = False, big = True )
[707]418
[802]419    mapping.addGlobal( 'seg_pic', pic_base, pic_size, '__W_',
[730]420                       vtype = 'PERI', x = 0, y = 0, pseg = 'PIC',
[817]421                       local = False, big = True )
[707]422
[802]423    mapping.addGlobal( 'seg_rom', rom_base, rom_size, 'CXW_',
[730]424                       vtype = 'PERI', x = 0, y = 0, pseg = 'ROM',
[817]425                       local = False, big = True )
[707]426
[817]427    ### global vsegs for internal peripherals : non local / small pages   
428    ### allocated in all clusters with name indexed by (x,y)
429    ### as vbase address is incremented by (cluster_xy * vseg_increment)
[714]430    for x in xrange( x_size ):
431        for y in xrange( y_size ):
[817]432            offset = ((x << y_width) + y) * peri_increment
[707]433
[714]434            mapping.addGlobal( 'seg_xcu_%d_%d' %(x,y), xcu_base + offset, xcu_size,
[817]435                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'XCU',
436                               local = False, big = False )
[707]437
[714]438            mapping.addGlobal( 'seg_mmc_%d_%d' %(x,y), mmc_base + offset, mmc_size,
[817]439                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'MMC',
440                               local = False, big = False )
[707]441
[972]442            if ( mwr_type != 'NONE' ):
443                mapping.addGlobal( 'seg_mwr_%d_%d' %(x,y), mwr_base + offset, mwr_size,
444                                   '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'MWR',
445                                   local = False, big = False )
446
[707]447    return mapping
448
[938]449################################# platform test ####################################
[707]450
451if __name__ == '__main__':
452
[730]453    mapping = arch( x_size    = 2,
454                    y_size    = 2,
455                    nb_procs  = 2 )
[707]456
457#   print mapping.netbsd_dts()
458
459    print mapping.xml()
460
461#   print mapping.giet_vsegs()
462
[802]463
[707]464# Local Variables:
465# tab-width: 4;
466# c-basic-offset: 4;
467# c-file-offsets:((innamespace . 0)(inline-open . 0));
468# indent-tabs-mode: nil;
469# End:
470#
471# vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
472
Note: See TracBrowser for help on using the repository browser.