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

Last change on this file since 836 was 817, checked in by alain, 10 years ago

Using both BPP (Big Physical Pages) and SPP (Small Physical Pages)
for Boot an kernel mapping on tsar_generic_iob platform.

  • Property svn:executable set to *
File size: 16.9 KB
RevLine 
[707]1
[802]2from math import log, ceil
[707]3from mapping import *
4
5#######################################################################################
[714]6#   file   : arch.py  (for the tsar_generic_iob architecture)
[707]7#   date   : may 2014
8#   author : Alain Greiner
9#######################################################################################
[802]10#  This file contains a mapping generator for the "tsar_generic_iob" platform.
[707]11#  This includes both the hardware architecture (clusters, processors, peripherals,
12#  physical space segmentation) and the mapping of all kernel objects (global vsegs).
13#  This platform includes 6 external peripherals, accessible through two IO_Bridge
[730]14#  components located in cluster [0,0] and cluster [x_size-1, y_size-1].
15#  Available peripherals are: TTY, BDV, FBF, ROM, NIC, CMA.
[714]16#
17#  The "constructor" parameters are:
18#  - x_size         : number of clusters in a row
19#  - y_size         : number of clusters in a column
20#  - nb_procs       : number of processors per cluster
[817]21#  - fbf_width      : frame_buffer width = frame_buffer heigth
[714]22#
[754]23#  The "hidden" parameters (defined below) are:
[714]24#  - nb_ttys        : number of TTY channels
25#  - nb_nics        : number of NIC channels
26#  - x_io           : cluster_io x coordinate
27#  - y_io           : cluster_io y coordinate
28#  - x_width        : number of bits for x coordinate
29#  - y_width        : number of bits for y coordinate
30#  - paddr_width    : number of bits for physical address
31#  - irq_per_proc   : number of input IRQs per processor
32#  - use_ramdisk    : use a ramdisk when True
[817]33#  - vseg_increment : address increment for replicated peripherals
34#
35# Regarding physical memory allocation, there is one allocator per cluster:
36# - We use only one big physical page (2 Mbytes) for the four boot vsegs,
37#   allocated in cluster[0,0], identity mapping.
38# - We use one big page per cluster for the kernel vsegs.
39#   The kernel_code, kernel_init and kernel_ptab can be replicated in all clusters.
40#   The kernel_data and kernel_uncdata shared vsegs are only mapped in cluster[0,0].
41# - We use 8 small physical pages (4 Kbytes) per cluster for the schedulers.
42# - We use one big page for each external peripheral in IO cluster,
43# - We use one small page per cluster for each internal peripheral.
44###################################################################################
[707]45
[714]46########################
47def arch( x_size    = 2,
48          y_size    = 2,
[817]49          nb_procs  = 2,
50          fbf_width = 128 ):
[714]51
52    ### define architecture constants
53
[817]54    nb_ttys         = 1
55    nb_nics         = 2 
56    x_io            = 0
57    y_io            = 0
58    x_width         = 4
59    y_width         = 4
60    p_width         = 4
61    paddr_width     = 40
62    irq_per_proc    = 4
63    use_ramdisk     = False
64    peri_increment  = 0x10000    # distributed peripherals vbase address increment
65    sched_increment = 0x10000    # distributed schedulers vbase address increment
66    ptab_increment  = 0x200000   # distributed page tables vbase address increment
[802]67
[707]68    ### parameters checking
[714]69
[802]70    assert( nb_procs <= (1 << p_width) )
[707]71
[802]72    assert( (x_size == 1) or (x_size == 2) or (x_size == 4)
[764]73             or (x_size == 8) or (x_size == 16) )
[707]74
[802]75    assert( (y_size == 1) or (y_size == 2) or (y_size == 4)
[707]76             or (y_size == 8) or (y_size == 16) )
77
[714]78    assert( nb_ttys == 1 )
[707]79
80    assert( ((x_io == 0) and (y_io == 0)) or
81            ((x_io == x_size-1) and (y_io == y_size-1)) )
82
[817]83    platform_name  = 'tsar_iob_%d_%d_%d_%d' % ( x_size, y_size, nb_procs, fbf_width )
[802]84
[817]85    ### define replicated physical segments
86    ### These segments are replicated in all clusters
[707]87
88    ram_base = 0x0000000000
[714]89    ram_size = 0x4000000                   # 64 Mbytes
[707]90
[802]91    xcu_base = 0x00B0000000
92    xcu_size = 0x1000                      # 4 Kbytes
[707]93
94    dma_base = 0x00B1000000
[817]95    dma_size = 0x1000                      # 4 Kbytes
[707]96
[802]97    mmc_base = 0x00B2000000
[714]98    mmc_size = 0x1000                      # 4 Kbytes
[707]99
[817]100    ### define physical segments for external peripherals
101    ## These segments are only defined in cluster_io
102
[707]103    offset_io = ((x_io << y_width) + y_io) << (paddr_width - x_width - y_width)
104
105    bdv_base  = 0x00B3000000 + offset_io
[714]106    bdv_size  = 0x1000                     # 4kbytes
[707]107
108    tty_base  = 0x00B4000000 + offset_io
[714]109    tty_size  = 0x4000                     # 16 Kbytes
[707]110
111    nic_base  = 0x00B5000000 + offset_io
[714]112    nic_size  = 0x80000                    # 512 kbytes
[707]113
114    cma_base  = 0x00B6000000 + offset_io
[714]115    cma_size  = 0x1000 * 2 * nb_nics       # 4 kbytes * 2 * nb_nics
[707]116
117    fbf_base  = 0x00B7000000 + offset_io
[714]118    fbf_size  = fbf_width * fbf_width      # fbf_width * fbf_width bytes
[707]119
120    pic_base  = 0x00B8000000 + offset_io
[714]121    pic_size  = 0x1000                     # 4 Kbytes
[707]122
123    iob_base  = 0x00BE000000 + offset_io
[817]124    iob_size  = 0x1000                     # 4 bytes
[707]125
126    rom_base  = 0x00BFC00000 + offset_io
[714]127    rom_size  = 0x4000                     # 16 Kbytes
[707]128
[754]129    ### define  bootloader vsegs base addresses and sizes
[817]130    ### We want to pack these 4 vsegs in the same big page
131    ### => boot cost is one BPP in cluster[0][0]
[707]132
[714]133    boot_mapping_vbase   = 0x00000000      # ident
[764]134    boot_mapping_size    = 0x00080000      # 512 Kbytes
[707]135
[762]136    boot_code_vbase      = 0x00080000      # ident
[802]137    boot_code_size       = 0x00040000      # 256 Kbytes
138
[762]139    boot_data_vbase      = 0x000C0000      # ident
[764]140    boot_data_size       = 0x00080000      # 512 Kbytes
[707]141
[762]142    boot_stack_vbase     = 0x00140000      # ident
[714]143    boot_stack_size      = 0x00050000      # 320 Kbytes
[707]144
[754]145    ### define kernel vsegs base addresses and sizes
[817]146    ### code, init, ptab & sched vsegs are replicated in all clusters.
147    ### data & uncdata vsegs are only mapped in cluster[0][0].
148    ### - We pack code, init, data vsegs in the same BIG page.
149    ### - We use another BIG page for the ptab vseg.
150    ### - We use 2*nb_procs SMALL pages for the sched vseg.
151    ### - we use one SMALL page for uncdata
152    ### => kernel cost is 2 BPPs and (2*n + 1) SPPs per cluster.
[707]153
[802]154    kernel_code_vbase    = 0x80000000
[817]155    kernel_code_size     = 0x00080000      # 512 Kbytes per cluster
[707]156
[817]157    kernel_init_vbase    = 0x80080000
158    kernel_init_size     = 0x00080000      # 512 Kbytes per cluster
[707]159
[817]160    kernel_data_vbase    = 0x80100000
161    kernel_data_size     = 0x00100000      # 1 Mbytes in cluster[0][0]
[707]162
[817]163    kernel_ptab_vbase    = 0xE0000000
164    kernel_ptab_size     = 0x00200000      # 2 Mbytes per cluster
[707]165
[817]166    kernel_uncdata_vbase = 0x90000000
167    kernel_uncdata_size  = 0x00001000      # 4 Kbytes
[707]168
[817]169    kernel_sched_vbase   = 0xA0000000   
170    kernel_sched_size    = 0x00002000*nb_procs  # 8 Kbytes per proc per cluster
171
[707]172    ### create mapping
173
[817]174    mapping = Mapping( name           = platform_name, 
175                       x_size         = x_size,       
176                       y_size         = y_size,       
177                       nprocs         = nb_procs,     
178                       x_width        = x_width,       
179                       y_width        = y_width,       
[802]180                       p_width        = p_width,
[817]181                       paddr_width    = paddr_width,   
182                       coherence      = True,         
183                       irq_per_proc   = irq_per_proc, 
184                       use_ramdisk    = use_ramdisk, 
185                       x_io           = x_io,         
[714]186                       y_io           = y_io,
[802]187                       peri_increment = peri_increment,
188                       ram_base       = ram_base,
189                       ram_size       = ram_size )
[707]190
191    ###  external peripherals (accessible in cluster[0,0] only for this mapping)
192
193    iob = mapping.addPeriph( 'IOB', base = iob_base, size = iob_size, ptype = 'IOB' )
194
195    bdv = mapping.addPeriph( 'BDV', base = bdv_base, size = bdv_size, ptype = 'IOC', subtype = 'BDV' )
196
197    tty = mapping.addPeriph( 'TTY', base = tty_base, size = tty_size, ptype = 'TTY', channels = nb_ttys )
198
[802]199    nic = mapping.addPeriph( 'NIC', base = nic_base, size = nic_size, ptype = 'NIC', channels = nb_nics )
[707]200
201    cma = mapping.addPeriph( 'CMA', base = cma_base, size = cma_size, ptype = 'CMA', channels = 2*nb_nics )
202
[714]203    fbf = mapping.addPeriph( 'FBF', base = fbf_base, size = fbf_size, ptype = 'FBF', arg = fbf_width )
[707]204
205    rom = mapping.addPeriph( 'ROM', base = rom_base, size = rom_size, ptype = 'ROM' )
206
207    pic = mapping.addPeriph( 'PIC', base = pic_base, size = pic_size, ptype = 'PIC', channels = 32 )
208
[710]209    mapping.addIrq( pic, index = 0, isrtype = 'ISR_NIC_RX', channel = 0 )
210    mapping.addIrq( pic, index = 1, isrtype = 'ISR_NIC_RX', channel = 1 )
[707]211
[710]212    mapping.addIrq( pic, index = 2, isrtype = 'ISR_NIC_TX', channel = 0 )
213    mapping.addIrq( pic, index = 3, isrtype = 'ISR_NIC_TX', channel = 1 )
[707]214
[710]215    mapping.addIrq( pic, index = 4, isrtype = 'ISR_CMA'   , channel = 0 )
216    mapping.addIrq( pic, index = 5, isrtype = 'ISR_CMA'   , channel = 1 )
217    mapping.addIrq( pic, index = 6, isrtype = 'ISR_CMA'   , channel = 2 )
218    mapping.addIrq( pic, index = 7, isrtype = 'ISR_CMA'   , channel = 3 )
[707]219
[710]220    mapping.addIrq( pic, index = 8, isrtype = 'ISR_BDV'   , channel = 0 )
[707]221
[710]222    mapping.addIrq( pic, index = 9, isrtype = 'ISR_TTY_RX', channel = 0 )
223
[802]224    ### hardware components replicated in all clusters
[707]225
226    for x in xrange( x_size ):
227        for y in xrange( y_size ):
228            cluster_xy = (x << y_width) + y;
229            offset     = cluster_xy << (paddr_width - x_width - y_width)
230
231            ram = mapping.addRam( 'RAM', base = ram_base + offset, size = ram_size )
232
[802]233            mmc = mapping.addPeriph( 'MMC', base = mmc_base + offset, size = mmc_size,
[707]234                                     ptype = 'MMC' )
235
[802]236            dma = mapping.addPeriph( 'DMA', base = dma_base + offset, size = dma_size,
237                                     ptype = 'DMA', channels = nb_procs )
[707]238
[802]239            xcu = mapping.addPeriph( 'XCU', base = xcu_base + offset, size = xcu_size,
[710]240                                     ptype = 'XCU', channels = nb_procs * irq_per_proc, arg = 16 )
[707]241
[710]242            # MMC IRQ replicated in all clusters
243            mapping.addIrq( xcu, index = 0, isrtype = 'ISR_MMC' )
244
[770]245            # DMA IRQ replicated in all clusters
246            for i in xrange ( dma.channels ):
247                mapping.addIrq( xcu, index = 1+i, isrtype = 'ISR_DMA',
248                        channel = i )
249
[707]250            # processors
251            for p in xrange ( nb_procs ):
252                mapping.addProc( x, y, p )
253
[817]254    ### global vsegs for boot_loader
255    ### we want to pack those 4 vsegs in the same big page
256    ### => same flags CXW_ / identity mapping / non local / big page
[707]257
[730]258    mapping.addGlobal( 'seg_boot_mapping', boot_mapping_vbase, boot_mapping_size,
[817]259                       'CXW_', vtype = 'BLOB'  , x = 0, y = 0, pseg = 'RAM',
260                       identity = True , local = False, big = True )
[707]261
[730]262    mapping.addGlobal( 'seg_boot_code', boot_code_vbase, boot_code_size,
263                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
[817]264                       identity = True , local = False, big = True )
[707]265
[730]266    mapping.addGlobal( 'seg_boot_data', boot_data_vbase, boot_data_size,
[817]267                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
268                       identity = True , local = False, big = True )
[707]269
[730]270    mapping.addGlobal( 'seg_boot_stack', boot_stack_vbase, boot_stack_size,
[817]271                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
272                       identity = True , local = False, big = True )
[707]273
[817]274    ### global vsegs kernel_code, kernel_init : local / big page
275    ### replicated in all clusters with the same name (same vbase)
276    for x in xrange( x_size ):
277        for y in xrange( y_size ):
278            mapping.addGlobal( 'seg_kernel_code', kernel_code_vbase, kernel_code_size,
279                               'CXW_', vtype = 'ELF', x = x , y = y , pseg = 'RAM',
280                               binpath = 'build/kernel/kernel.elf', 
281                               local = True, big = True )
[707]282
[817]283            mapping.addGlobal( 'seg_kernel_init', kernel_init_vbase, kernel_init_size,
284                               'CXW_', vtype = 'ELF', x = x , y = y , pseg = 'RAM',
285                               binpath = 'build/kernel/kernel.elf', 
286                               local = True, big = True )
[707]287
[817]288    ### global vseg kernel_data: non local / big page
289    ### Only mapped in cluster[0][0]
290    mapping.addGlobal( 'seg_kernel_data', kernel_data_vbase, kernel_data_size, 
291                       'CXW_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM', 
292                       binpath = 'build/kernel/kernel.elf', 
293                       local = False, big = True )
[707]294
[817]295    ### global vseg kernel_uncdata: non local / small page
296    ### Only mapped in cluster[0][0]
297    mapping.addGlobal( 'seg_kernel_uncdata', kernel_uncdata_vbase, kernel_uncdata_size,
298                       '__W_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM', 
299                       binpath = 'build/kernel/kernel.elf', 
300                       local = False, big = False )
[707]301
[817]302    ### Global vsegs kernel_ptab_x_y: non local / big pages
303    ### replicated in all clusters with name indexed by (x,y)
304    ### as vbase address is incremented by (cluster_xy * vseg_increment)
305    for x in xrange( x_size ):
306        for y in xrange( y_size ):
307            offset = ((x << y_width) + y) * ptab_increment
308            mapping.addGlobal( 'seg_kernel_ptab_%d_%d' %(x,y), kernel_ptab_vbase + offset , kernel_ptab_size,
309                               'CXW_', vtype = 'PTAB', x = x, y = y, pseg = 'RAM', 
310                               local = False , big = True )
[734]311
[817]312    ### global vsegs kernel_sched : non local / small pages
313    ### allocated in all clusters with name indexed by (x,y)
314    ### as vbase address is incremented by (cluster_xy * vseg_increment)
315    for x in xrange( x_size ):
316        for y in xrange( y_size ):
317            offset = ((x << y_width) + y) * sched_increment
318            mapping.addGlobal( 'seg_kernel_sched_%d_%d' %(x,y), kernel_sched_vbase + offset , kernel_sched_size,
319                               'C_W_', vtype = 'SCHED', x = x , y = y , pseg = 'RAM',
320                               local = False, big = False )
[707]321
[817]322    ### global vsegs for external peripherals : non local / big page
[802]323    mapping.addGlobal( 'seg_iob', iob_base, iob_size, '__W_',
324                       vtype = 'PERI', x = 0, y = 0, pseg = 'IOB',
[817]325                       local = False, big = True )
[707]326
[802]327    mapping.addGlobal( 'seg_bdv', bdv_base, bdv_size, '__W_',
[730]328                       vtype = 'PERI', x = 0, y = 0, pseg = 'BDV',
[817]329                       local = False, big = True )
[707]330
[802]331    mapping.addGlobal( 'seg_tty', tty_base, tty_size, '__W_',
[730]332                       vtype = 'PERI', x = 0, y = 0, pseg = 'TTY',
[817]333                       local = False, big = True )
[707]334
[802]335    mapping.addGlobal( 'seg_nic', nic_base, nic_size, '__W_',
[730]336                       vtype = 'PERI', x = 0, y = 0, pseg = 'NIC',
[817]337                       local = False, big = True )
[707]338
[802]339    mapping.addGlobal( 'seg_cma', cma_base, cma_size, '__W_',
[730]340                       vtype = 'PERI', x = 0, y = 0, pseg = 'CMA',
[817]341                       local = False, big = True )
[707]342
[802]343    mapping.addGlobal( 'seg_fbf', fbf_base, fbf_size, '__W_',
[730]344                       vtype = 'PERI', x = 0, y = 0, pseg = 'FBF',
[817]345                       local = False, big = True )
[707]346
[802]347    mapping.addGlobal( 'seg_pic', pic_base, pic_size, '__W_',
[730]348                       vtype = 'PERI', x = 0, y = 0, pseg = 'PIC',
[817]349                       local = False, big = True )
[707]350
[802]351    mapping.addGlobal( 'seg_rom', rom_base, rom_size, 'CXW_',
[730]352                       vtype = 'PERI', x = 0, y = 0, pseg = 'ROM',
[817]353                       local = False, big = True )
[707]354
[817]355    ### global vsegs for internal peripherals : non local / small pages   
356    ### allocated in all clusters with name indexed by (x,y)
357    ### as vbase address is incremented by (cluster_xy * vseg_increment)
[714]358    for x in xrange( x_size ):
359        for y in xrange( y_size ):
[817]360            offset = ((x << y_width) + y) * peri_increment
[707]361
[714]362            mapping.addGlobal( 'seg_xcu_%d_%d' %(x,y), xcu_base + offset, xcu_size,
[817]363                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'XCU',
364                               local = False, big = False )
[707]365
[714]366            mapping.addGlobal( 'seg_dma_%d_%d' %(x,y), dma_base + offset, dma_size,
[817]367                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'DMA',
368                               local = False, big = False )
[707]369
[714]370            mapping.addGlobal( 'seg_mmc_%d_%d' %(x,y), mmc_base + offset, mmc_size,
[817]371                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'MMC',
372                               local = False, big = False )
[707]373
374    ### return mapping ###
375
376    return mapping
377
378################################# platform test #######################################################
379
380if __name__ == '__main__':
381
[730]382    mapping = arch( x_size    = 2,
383                    y_size    = 2,
384                    nb_procs  = 2 )
[707]385
386#   print mapping.netbsd_dts()
387
388    print mapping.xml()
389
390#   print mapping.giet_vsegs()
391
[802]392
[707]393# Local Variables:
394# tab-width: 4;
395# c-basic-offset: 4;
396# c-file-offsets:((innamespace . 0)(inline-open . 0));
397# indent-tabs-mode: nil;
398# End:
399#
400# vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
401
Note: See TracBrowser for help on using the repository browser.