source: trunk/platforms/tsar_generic_leti/arch.py @ 937

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

Reducing the number of external TTY terminals to 8, in both the top.cpp and arch.py files.

  • Property svn:executable set to *
File size: 18.4 KB
Line 
1#!/usr/bin/env python
2
3from math import log, ceil
4from mapping import *
5
6###############################################################################
7#   file   : arch.py  (for the tsar_generic_leti architecture)
8#   date   : may 2014
9#   author : Alain Greiner
10###############################################################################
11#  This file contains a mapping generator for the "tsar_generic_leti" platform.
12#  This includes both the hardware architecture (clusters, processors,
13#  peripherals, physical space segmentation) and the mapping of all boot
14#  and kernel objects (global vsegs).
15#
16#  The x_size & y_size parameters define the total number of clusters.
17#  The upper row (y = y_size-1) does not contain processors or memory.
18#
19#  It does not use the IOB component:
20#  The external peripherals are located in cluster[x_size-1][y_size-1].
21#
22#  It does not use an external ROM, as the preloader code is (pre)loaded
23#  at address 0x0, in the physical memory of cluster[0][0].
24#
25#  It can use an - optional - RAMDISK located in cluster[0][0].
26#
27#  The others hardware parameters are:
28#  - fbf_width      : frame_buffer width = frame_buffer heigth
29#  - nb_ttys        : number of TTY channels
30#  - nb_nics        : number of NIC channels
31#  - nb_cmas        : number of CMA channels
32#  - irq_per_proc   : number of input IRQs per processor
33#  - use_ramdisk    : use a RAMDISK when True
34#  - peri_increment : address increment for replicated peripherals
35#
36#  Regarding the boot and kernel vsegs mapping :
37#  - We use one big physical page (2 Mbytes) for the preloader and the four
38#    boot vsegs, all allocated in cluster[0,0].
39#  - We use the 16 next big pages in cluster[0][0] to implement the RAMDISK.
40#  - We use one big page per cluster for the replicated kernel code vsegs.
41#  - We use one big page in cluster[0][0] for the kernel data vseg.
42#  - We use one big page per cluster for the distributed kernel heap vsegs.
43#  - We use one big page per cluster for the distributed ptab vsegs.
44#  - We use small physical pages (4 Kbytes) per cluster for the schedulers.
45#  - We use one big page for each external peripheral in IO cluster,
46#  - We use one small page per cluster for each internal peripheral.
47###############################################################################
48
49########################
50def arch( x_size    = 2,
51          y_size    = 2,
52          nb_procs  = 4,
53          nb_ttys   = 1,
54          fbf_width = 128 ):
55
56    ### define architecture constants
57
58    nb_nics         = 1
59    nb_cmas         = 2
60    x_io            = x_size - 1
61    y_io            = y_size - 1
62    x_width         = 4
63    y_width         = 4
64    p_width         = 2
65    paddr_width     = 40
66    irq_per_proc    = 4
67    use_ramdisk     = False
68    peri_increment  = 0x10000     # distributed peripherals vbase increment
69    reset_address   = 0x00000000  # wired preloader pbase address
70
71    ### parameters checking
72
73    assert( nb_procs <= (1 << p_width) )
74
75    assert( x_size <= (1 << x_width) )
76
77    assert( y_size <= (1 << y_width) )
78
79    ### define type and name
80
81    platform_type  = 'tsar_leti'
82    platform_name  = '%s_%d_%d_%d' % (platform_type, x_size, y_size, nb_procs )
83
84    ### define physical segments replicated in all clusters
85    ### the base address is extended by the cluster_xy (8 bits)
86
87    ram_base = 0x00000000
88    ram_size = 0x4000000                   # 64 Mbytes
89
90    xcu_base = 0xF0000000
91    xcu_size = 0x1000                      # 4 Kbytes
92
93    mmc_base = 0xF1000000
94    mmc_size = 0x1000                      # 4 Kbytes
95
96    ### define physical segments for external peripherals
97    ## These segments are only defined in cluster_io
98
99    cluster_xy = ((x_io << y_width) + y_io) << (paddr_width - x_width - y_width)
100
101    bdv_base  = 0xF2000000 + cluster_xy
102    bdv_size  = 0x1000                     # 4kbytes
103
104    tty_base  = 0xF4000000 + cluster_xy
105    tty_size  = 0x4000                     # 16 Kbytes
106
107    nic_base  = 0xF7000000 + cluster_xy
108    nic_size  = 0x80000                    # 512 kbytes
109
110    cma_base  = 0xF8000000 + cluster_xy
111    cma_size  = 0x1000 * 2 * nb_nics       # 4 kbytes * 2 * nb_nics
112
113    pic_base  = 0xF9000000 + cluster_xy
114    pic_size  = 0x1000                     # 4 Kbytes
115
116    fbf_base  = 0xF3000000 + cluster_xy
117    fbf_size  = fbf_width * fbf_width      # fbf_width * fbf_width bytes
118
119
120    ### define preloader & bootloader vsegs base addresses and sizes
121    ### We want to pack these 5 vsegs in the same big page
122    ### => boot cost is one BPP in cluster[0][0]
123
124    preloader_vbase      = 0x00000000      # ident
125    preloader_size       = 0x00010000      # 64 Kbytes
126
127    boot_mapping_vbase   = 0x00010000      # ident
128    boot_mapping_size    = 0x00080000      # 512 Kbytes
129
130    boot_code_vbase      = 0x00090000      # ident
131    boot_code_size       = 0x00040000      # 256 Kbytes
132
133    boot_data_vbase      = 0x000D0000      # ident
134    boot_data_size       = 0x000C0000      # 768 Kbytes
135
136    boot_stack_vbase     = 0x00190000      # ident
137    boot_stack_size      = 0x00070000      # 448 Kbytes
138
139    ### define ramdisk vseg / must be identity mapping in cluster[0][0]
140    ### occupies 15 BPP after the boot 
141    ramdisk_vbase        = 0x00200000
142    ramdisk_size         = 0x02000000      # 32 Mbytes
143
144    ### define kernel vsegs base addresses and sizes
145    ### code, init, ptab, heap & sched vsegs are replicated in all clusters.
146    ### data & uncdata vsegs are only mapped in cluster[0][0].
147
148    kernel_code_vbase    = 0x80000000
149    kernel_code_size     = 0x00100000      # 1 Mbytes per cluster
150
151    kernel_init_vbase    = 0x80100000
152    kernel_init_size     = 0x00100000      # 1 Mbytes per cluster
153
154    kernel_data_vbase    = 0x90000000
155    kernel_data_size     = 0x00200000      # 2 Mbytes in cluster[0][0]
156
157    kernel_uncdata_vbase = 0x90200000
158    kernel_uncdata_size  = 0x00001000      # 4 Kbytes in cluster[0][0]
159
160    kernel_ptab_vbase    = 0xE0000000
161    kernel_ptab_size     = 0x00200000      # 2 Mbytes per cluster
162
163    kernel_heap_vbase    = 0xD0000000
164    kernel_heap_size     = 0x00200000      # 2 Mbytes per cluster
165
166    kernel_sched_vbase   = 0xA0000000
167    kernel_sched_size    = 0x00002000 * nb_procs # 8 kbytes per proc per cluster
168
169    #####################
170    ### create mapping
171    #####################
172
173    mapping = Mapping( name           = platform_name,
174                       p_type         = platform_type,
175                       x_size         = x_size,
176                       y_size         = y_size,
177                       nprocs         = nb_procs,
178                       x_width        = x_width,
179                       y_width        = y_width,
180                       p_width        = p_width,
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,
186                       y_io           = y_io,
187                       peri_increment = peri_increment,
188                       reset_address  = reset_address,
189                       ram_base       = ram_base,
190                       ram_size       = ram_size )
191
192    ###########################
193    ### Hardware Description
194    ###########################
195
196    for x in xrange( x_size ):
197        for y in xrange( y_size ):
198            cluster_xy = (x << y_width) + y;
199            offset     = cluster_xy << (paddr_width - x_width - y_width)
200 
201            ### components replicated in all clusters but the upper row
202            if ( y < (y_size - 1) ):
203
204                ram = mapping.addRam( 'RAM', base = ram_base + offset, 
205                                      size = ram_size )
206
207                mmc = mapping.addPeriph( 'MMC', base = mmc_base + offset, 
208                                         size = mmc_size, ptype = 'MMC' )
209
210                xcu = mapping.addPeriph( 'XCU', base = xcu_base + offset, 
211                                         size = xcu_size, ptype = 'XCU', 
212                                         channels = nb_procs * irq_per_proc, arg = 16 )
213
214                mapping.addIrq( xcu, index = 8, isrtype = 'ISR_MMC' )
215
216                for p in xrange ( nb_procs ):
217                    mapping.addProc( x, y, p )
218
219            ###  external peripherals in cluster_io
220            if ( (x==x_io) and (y==y_io) ):
221
222                bdv = mapping.addPeriph( 'BDV', base = bdv_base, size = bdv_size, 
223                                         ptype = 'IOC', subtype = 'BDV' )
224
225                tty = mapping.addPeriph( 'TTY', base = tty_base, size = tty_size, 
226                                         ptype = 'TTY', channels = nb_ttys )
227
228                nic = mapping.addPeriph( 'NIC', base = nic_base, size = nic_size, 
229                                         ptype = 'NIC', channels = nb_nics )
230
231                cma = mapping.addPeriph( 'CMA', base = cma_base, size = cma_size, 
232                                         ptype = 'CMA', channels = nb_cmas )
233
234                fbf = mapping.addPeriph( 'FBF', base = fbf_base, size = fbf_size, 
235                                         ptype = 'FBF', arg = fbf_width )
236
237                pic = mapping.addPeriph( 'PIC', base = pic_base, size = pic_size, 
238                                         ptype = 'PIC', channels = 32 )
239
240                mapping.addIrq( pic, index = 0 , isrtype = 'ISR_NIC_RX', channel = 0 )
241                mapping.addIrq( pic, index = 1 , isrtype = 'ISR_NIC_RX', channel = 1 )
242
243                mapping.addIrq( pic, index = 2 , isrtype = 'ISR_NIC_TX', channel = 0 )
244                mapping.addIrq( pic, index = 3 , isrtype = 'ISR_NIC_TX', channel = 1 )
245
246                mapping.addIrq( pic, index = 4 , isrtype = 'ISR_CMA'   , channel = 0 )
247                mapping.addIrq( pic, index = 5 , isrtype = 'ISR_CMA'   , channel = 1 )
248                mapping.addIrq( pic, index = 6 , isrtype = 'ISR_CMA'   , channel = 2 )
249                mapping.addIrq( pic, index = 7 , isrtype = 'ISR_CMA'   , channel = 3 )
250
251                mapping.addIrq( pic, index = 8 , isrtype = 'ISR_BDV'   , channel = 0 )
252
253                mapping.addIrq( pic, index = 16, isrtype = 'ISR_TTY_RX', channel = 0 )
254                mapping.addIrq( pic, index = 17, isrtype = 'ISR_TTY_RX', channel = 1 )
255                mapping.addIrq( pic, index = 18, isrtype = 'ISR_TTY_RX', channel = 2 )
256                mapping.addIrq( pic, index = 19, isrtype = 'ISR_TTY_RX', channel = 3 )
257                mapping.addIrq( pic, index = 20, isrtype = 'ISR_TTY_RX', channel = 4 )
258                mapping.addIrq( pic, index = 21, isrtype = 'ISR_TTY_RX', channel = 5 )
259                mapping.addIrq( pic, index = 22, isrtype = 'ISR_TTY_RX', channel = 6 )
260                mapping.addIrq( pic, index = 23, isrtype = 'ISR_TTY_RX', channel = 7 )
261
262    ###################################
263    ### boot & kernel vsegs mapping
264    ###################################
265
266    ### global vsegs for preloader & boot_loader are mapped in cluster[0][0]
267    ### we want to pack those 5 vsegs in the same big page
268    ### => same flags CXW_ / identity mapping / non local / big page
269
270    mapping.addGlobal( 'seg_preloader', preloader_vbase, preloader_size,
271                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
272                       identity = True, local = False, big = True )
273
274    mapping.addGlobal( 'seg_boot_mapping', boot_mapping_vbase, boot_mapping_size,
275                       'CXW_', vtype = 'BLOB'  , x = 0, y = 0, pseg = 'RAM',
276                       identity = True, local = False, big = True )
277
278    mapping.addGlobal( 'seg_boot_code', boot_code_vbase, boot_code_size,
279                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
280                       identity = True, local = False, big = True )
281
282    mapping.addGlobal( 'seg_boot_data', boot_data_vbase, boot_data_size,
283                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
284                       identity = True, local = False, big = True )
285
286    mapping.addGlobal( 'seg_boot_stack', boot_stack_vbase, boot_stack_size,
287                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
288                       identity = True, local = False, big = True )
289
290    ### global vseg for RAM-DISK in cluster[0][0]
291    ### identity mapping / non local / big pages
292    if use_ramdisk:
293
294        mapping.addGlobal( 'seg_ramdisk', ramdisk_vbase, ramdisk_size,
295                           'C_W_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
296                           identity = True, local = True, big = True )
297
298    ### global vsegs kernel_code, kernel_init : local / big page
299    ### replicated in all clusters containing processors
300    ### same content => same name / same vbase
301    for x in xrange( x_size ):
302        for y in xrange( y_size - 1 ):
303
304            mapping.addGlobal( 'seg_kernel_code', 
305                               kernel_code_vbase, kernel_code_size,
306                               'CXW_', vtype = 'ELF', x = x, y = y, pseg = 'RAM',
307                               binpath = 'build/kernel/kernel.elf',
308                               local = True, big = True )
309
310            mapping.addGlobal( 'seg_kernel_init', 
311                               kernel_init_vbase, kernel_init_size,
312                               'CXW_', vtype = 'ELF', x = x, y = y, pseg = 'RAM',
313                               binpath = 'build/kernel/kernel.elf',
314                               local = True, big = True )
315
316    ### global vseg kernel_data: non local / big page
317    ### Only mapped in cluster[0][0]
318    mapping.addGlobal( 'seg_kernel_data', 
319                       kernel_data_vbase, kernel_data_size,
320                       'C_W_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM',
321                       binpath = 'build/kernel/kernel.elf', 
322                       local = False, big = True )
323
324    ### global vseg kernel_uncdata: non local / small page
325    ### Only mapped in cluster[0][0]
326    mapping.addGlobal( 'seg_kernel_uncdata', 
327                        kernel_uncdata_vbase, kernel_uncdata_size,
328                       '__W_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM',
329                       binpath = 'build/kernel/kernel.elf', 
330                       local = False, big = False )
331
332    ### Global vsegs kernel_ptab_x_y: non local / big page
333    ### replicated in all clusters containing processors
334    ### different content => name & vbase indexed by (x,y)
335    for x in xrange( x_size ):
336        for y in xrange( y_size - 1 ):
337            offset = ((x << y_width) + y) * kernel_ptab_size
338
339            mapping.addGlobal( 'seg_kernel_ptab_%d_%d' %(x,y), 
340                               kernel_ptab_vbase + offset, kernel_ptab_size,
341                               'CXW_', vtype = 'PTAB', x = x, y = y, pseg = 'RAM',
342                               local = False, big = True )
343
344    ### global vsegs kernel_sched : non local / small pages
345    ### allocated in all clusters containing processors
346    ### different content => name & vbase indexed by (x,y)
347    for x in xrange( x_size ):
348        for y in xrange( y_size - 1 ):
349            offset = ((x << y_width) + y) * kernel_ptab_size
350
351            mapping.addGlobal( 'seg_kernel_sched_%d_%d' %(x,y), 
352                               kernel_sched_vbase + offset , kernel_sched_size,
353                               'C_W_', vtype = 'SCHED', x = x, y = y, pseg = 'RAM',
354                               local = False, big = False )
355
356    ### global vsegs kernel_heap_x_y : non local / big pages
357    ### distributed in all clusters containing processors
358    ### different content => name & vbase indexed by (x,y)
359    for x in xrange( x_size ):
360        for y in xrange( y_size - 1 ):
361            offset = ((x << y_width) + y) * kernel_heap_size
362
363            mapping.addGlobal( 'seg_kernel_heap_%d_%d' %(x,y), 
364                               kernel_heap_vbase + offset , kernel_heap_size,
365                               'C_W_', vtype = 'HEAP', x = x , y = y , pseg = 'RAM',
366                               local = False, big = True )
367
368    ### global vsegs for external peripherals: non local / big page
369    ### only mapped in cluster_io
370    mapping.addGlobal( 'seg_bdv', 
371                       bdv_base, bdv_size,
372                       '__W_', vtype = 'PERI', x = x_io, y = y_io, pseg = 'BDV',
373                       local = False, big = True )
374
375    mapping.addGlobal( 'seg_tty', 
376                       tty_base, tty_size, 
377                       '__W_', vtype = 'PERI', x = x_io, y = y_io, pseg = 'TTY',
378                       local = False, big = True )
379
380    mapping.addGlobal( 'seg_nic', 
381                       nic_base, nic_size,
382                       '__W_', vtype = 'PERI', x = x_io, y = y_io, pseg = 'NIC',
383                       local = False, big = True )
384
385    mapping.addGlobal( 'seg_cma', 
386                       cma_base, cma_size,
387                       '__W_', vtype = 'PERI', x = x_io, y = y_io, pseg = 'CMA',
388                       local = False, big = True )
389
390    mapping.addGlobal( 'seg_fbf', 
391                       fbf_base, fbf_size,
392                       '__W_', vtype = 'PERI', x = x_io, y = y_io, pseg = 'FBF',
393                       local = False, big = True )
394
395    mapping.addGlobal( 'seg_pic', 
396                       pic_base, pic_size,
397                       '__W_', vtype = 'PERI', x = x_io, y = y_io, pseg = 'PIC',
398                       local = False, big = True )
399
400    ### global vsegs for internal peripherals : non local / small pages
401    ### allocated in all clusters containing processors
402    ### name and vbase indexed by (x,y)
403    for x in xrange( x_size ):
404        for y in xrange( y_size - 1 ):
405            offset = ((x << y_width) + y) * peri_increment
406
407            mapping.addGlobal( 'seg_xcu_%d_%d' %(x,y), 
408                               xcu_base + offset, xcu_size,
409                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'XCU',
410                               local = False, big = False )
411
412            mapping.addGlobal( 'seg_mmc_%d_%d' %(x,y), 
413                               mmc_base + offset, mmc_size,
414                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'MMC',
415                               local = False, big = False )
416
417    return mapping
418
419########################## platform test #############################################
420
421if __name__ == '__main__':
422
423    mapping = arch( x_size    = 2,
424                    y_size    = 2,
425                    nb_procs  = 2 )
426
427#   print mapping.netbsd_dts()
428
429    print mapping.xml()
430
431#   print mapping.giet_vsegs()
432
433
434# Local Variables:
435# tab-width: 4;
436# c-basic-offset: 4;
437# c-file-offsets:((innamespace . 0)(inline-open . 0));
438# indent-tabs-mode: nil;
439# End:
440#
441# vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
442
Note: See TracBrowser for help on using the repository browser.