Index: trunk/platforms/tsar_generic_iob/arch.py
===================================================================
--- trunk/platforms/tsar_generic_iob/arch.py	(revision 816)
+++ trunk/platforms/tsar_generic_iob/arch.py	(revision 817)
@@ -1,3 +1,2 @@
-#!/usr/bin/env python
 
 from math import log, ceil
@@ -20,9 +19,9 @@
 #  - y_size         : number of clusters in a column
 #  - nb_procs       : number of processors per cluster
+#  - fbf_width      : frame_buffer width = frame_buffer heigth
 #
 #  The "hidden" parameters (defined below) are:
 #  - nb_ttys        : number of TTY channels
 #  - nb_nics        : number of NIC channels
-#  - fbf_width      : frame_buffer width = frame_buffer heigth
 #  - x_io           : cluster_io x coordinate
 #  - y_io           : cluster_io y coordinate
@@ -32,27 +31,38 @@
 #  - irq_per_proc   : number of input IRQs per processor
 #  - use_ramdisk    : use a ramdisk when True
-#  - peri_increment : address increment for replicated peripherals
-####################################################################################
+#  - vseg_increment : address increment for replicated peripherals
+#
+# Regarding physical memory allocation, there is one allocator per cluster:
+# - We use only one big physical page (2 Mbytes) for the four boot vsegs,
+#   allocated in cluster[0,0], identity mapping.
+# - We use one big page per cluster for the kernel vsegs.
+#   The kernel_code, kernel_init and kernel_ptab can be replicated in all clusters.
+#   The kernel_data and kernel_uncdata shared vsegs are only mapped in cluster[0,0].
+# - We use 8 small physical pages (4 Kbytes) per cluster for the schedulers.
+# - We use one big page for each external peripheral in IO cluster,
+# - We use one small page per cluster for each internal peripheral.
+###################################################################################
 
 ########################
 def arch( x_size    = 2,
           y_size    = 2,
-          nb_procs  = 2 ):
+          nb_procs  = 2,
+          fbf_width = 128 ):
 
     ### define architecture constants
 
-    nb_ttys           = 1
-    nb_nics           = 2
-    fbf_width         = 128
-    x_io              = 0
-    y_io              = 0
-    x_width           = 4
-    y_width           = 4
-    p_width           = int(ceil(log(nb_procs, 2)))
-    paddr_width       = 40
-    irq_per_proc      = 4
-    use_ramdisk       = False
-    peri_increment    = 0x10000
-    distributed_ptabs = True
+    nb_ttys         = 1
+    nb_nics         = 2 
+    x_io            = 0
+    y_io            = 0
+    x_width         = 4
+    y_width         = 4
+    p_width         = 4
+    paddr_width     = 40
+    irq_per_proc    = 4
+    use_ramdisk     = False
+    peri_increment  = 0x10000    # distributed peripherals vbase address increment
+    sched_increment = 0x10000    # distributed schedulers vbase address increment 
+    ptab_increment  = 0x200000   # distributed page tables vbase address increment
 
     ### parameters checking
@@ -71,7 +81,8 @@
             ((x_io == x_size-1) and (y_io == y_size-1)) )
 
-    platform_name  = 'tsar_iob_%d_%d_%d' % ( x_size, y_size, nb_procs )
-
-    ### define physical segments
+    platform_name  = 'tsar_iob_%d_%d_%d_%d' % ( x_size, y_size, nb_procs, fbf_width )
+
+    ### define replicated physical segments
+    ### These segments are replicated in all clusters
 
     ram_base = 0x0000000000
@@ -82,9 +93,12 @@
 
     dma_base = 0x00B1000000
-    dma_size = 0x1000 * nb_procs           # 4 Kbytes * nb_procs
+    dma_size = 0x1000                      # 4 Kbytes 
 
     mmc_base = 0x00B2000000
     mmc_size = 0x1000                      # 4 Kbytes
 
+    ### define physical segments for external peripherals
+    ## These segments are only defined in cluster_io
+
     offset_io = ((x_io << y_width) + y_io) << (paddr_width - x_width - y_width)
 
@@ -108,5 +122,5 @@
 
     iob_base  = 0x00BE000000 + offset_io
-    iob_size  = 0x1000                     # 4kbytes
+    iob_size  = 0x1000                     # 4 bytes
 
     rom_base  = 0x00BFC00000 + offset_io
@@ -114,4 +128,6 @@
 
     ### define  bootloader vsegs base addresses and sizes
+    ### We want to pack these 4 vsegs in the same big page
+    ### => boot cost is one BPP in cluster[0][0]
 
     boot_mapping_vbase   = 0x00000000      # ident
@@ -128,34 +144,44 @@
 
     ### define kernel vsegs base addresses and sizes
+    ### code, init, ptab & sched vsegs are replicated in all clusters.
+    ### data & uncdata vsegs are only mapped in cluster[0][0].
+    ### - We pack code, init, data vsegs in the same BIG page.
+    ### - We use another BIG page for the ptab vseg.
+    ### - We use 2*nb_procs SMALL pages for the sched vseg.
+    ### - we use one SMALL page for uncdata
+    ### => kernel cost is 2 BPPs and (2*n + 1) SPPs per cluster.
 
     kernel_code_vbase    = 0x80000000
-    kernel_code_size     = 0x00020000      # 128 Kbytes
-
-    kernel_data_vbase    = 0x80020000
-    kernel_data_size     = 0x00020000      # 128 Kbytes
-
-    kernel_uncdata_vbase = 0x80040000
-    kernel_uncdata_size  = 0x00010000      # 64 Kbytes
-
-    kernel_init_vbase    = 0x80050000
-    kernel_init_size     = 0x00010000      # 64 Kbytes
-
-    kernel_sched_vbase   = 0xF0000000            # distributed in all clusters
-    kernel_sched_size    = 0x2000 * nb_procs     # 8 kbytes per processor
+    kernel_code_size     = 0x00080000      # 512 Kbytes per cluster
+
+    kernel_init_vbase    = 0x80080000
+    kernel_init_size     = 0x00080000      # 512 Kbytes per cluster
+
+    kernel_data_vbase    = 0x80100000
+    kernel_data_size     = 0x00100000      # 1 Mbytes in cluster[0][0]
+
+    kernel_ptab_vbase    = 0xE0000000
+    kernel_ptab_size     = 0x00200000      # 2 Mbytes per cluster
+
+    kernel_uncdata_vbase = 0x90000000
+    kernel_uncdata_size  = 0x00001000      # 4 Kbytes
+
+    kernel_sched_vbase   = 0xA0000000   
+    kernel_sched_size    = 0x00002000*nb_procs  # 8 Kbytes per proc per cluster
 
     ### create mapping
 
-    mapping = Mapping( name           = platform_name,
-                       x_size         = x_size,
-                       y_size         = y_size,
-                       procs_max      = nb_procs,
-                       x_width        = x_width,
-                       y_width        = y_width,
+    mapping = Mapping( name           = platform_name, 
+                       x_size         = x_size,        
+                       y_size         = y_size,        
+                       nprocs         = nb_procs,      
+                       x_width        = x_width,       
+                       y_width        = y_width,       
                        p_width        = p_width,
-                       paddr_width    = paddr_width,
-                       coherence      = True,
-                       irq_per_proc   = irq_per_proc,
-                       use_ramdisk    = use_ramdisk,
-                       x_io           = x_io,
+                       paddr_width    = paddr_width,   
+                       coherence      = True,          
+                       irq_per_proc   = irq_per_proc,  
+                       use_ramdisk    = use_ramdisk,  
+                       x_io           = x_io,          
                        y_io           = y_io,
                        peri_increment = peri_increment,
@@ -226,109 +252,123 @@
                 mapping.addProc( x, y, p )
 
-    ### global vsegs for boot_loader / identity mapping
+    ### global vsegs for boot_loader
+    ### we want to pack those 4 vsegs in the same big page
+    ### => same flags CXW_ / identity mapping / non local / big page
 
     mapping.addGlobal( 'seg_boot_mapping', boot_mapping_vbase, boot_mapping_size,
-                       'C_W_', vtype = 'BLOB'  , x = 0, y = 0, pseg = 'RAM',
-                       identity = True )
+                       'CXW_', vtype = 'BLOB'  , x = 0, y = 0, pseg = 'RAM',
+                       identity = True , local = False, big = True )
 
     mapping.addGlobal( 'seg_boot_code', boot_code_vbase, boot_code_size,
                        'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
-                       identity = True )
+                       identity = True , local = False, big = True )
 
     mapping.addGlobal( 'seg_boot_data', boot_data_vbase, boot_data_size,
-                       'C_W_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
-                       identity = True )
+                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
+                       identity = True , local = False, big = True )
 
     mapping.addGlobal( 'seg_boot_stack', boot_stack_vbase, boot_stack_size,
-                       'C_W_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
-                       identity = True )
-
-    ### the code global vsegs for kernel can be replicated in all clusters
-    ### if the page tables are distributed in all clusters.
-
-    if distributed_ptabs:
-        for x in xrange( x_size ):
-            for y in xrange( y_size ):
-                cluster_xy = (x << y_width) + y;
-
-                mapping.addGlobal( 'seg_kernel_code', kernel_code_vbase, kernel_code_size,
-                                   'CXW_', vtype = 'ELF', x = x , y = y , pseg = 'RAM',
-                                   binpath = 'build/kernel/kernel.elf', local = True )
-
-                mapping.addGlobal( 'seg_kernel_init', kernel_init_vbase, kernel_init_size,
-                                   'CXW_', vtype = 'ELF', x = x , y = y , pseg = 'RAM',
-                                   binpath = 'build/kernel/kernel.elf', local = True )
-    else:
-        mapping.addGlobal( 'seg_kernel_code', kernel_code_vbase, kernel_code_size,
-                           'CXW_', vtype = 'ELF', x = 0 , y = 0 , pseg = 'RAM',
-                            binpath = 'build/kernel/kernel.elf', local = False )
-
-        mapping.addGlobal( 'seg_kernel_init', kernel_init_vbase, kernel_init_size,
-                           'CXW_', vtype = 'ELF', x = 0 , y = 0 , pseg = 'RAM',
-                           binpath = 'build/kernel/kernel.elf', local = False )
-
-    ### shared global vsegs for kernel
-
-    mapping.addGlobal( 'seg_kernel_data', kernel_data_vbase, kernel_data_size,
-                       'C_W_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM',
-                       binpath = 'build/kernel/kernel.elf', local = False )
-
+                       'CXW_', vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM',
+                       identity = True , local = False, big = True )
+
+    ### global vsegs kernel_code, kernel_init : local / big page
+    ### replicated in all clusters with the same name (same vbase)
+    for x in xrange( x_size ):
+        for y in xrange( y_size ):
+            mapping.addGlobal( 'seg_kernel_code', kernel_code_vbase, kernel_code_size,
+                               'CXW_', vtype = 'ELF', x = x , y = y , pseg = 'RAM',
+                               binpath = 'build/kernel/kernel.elf', 
+                               local = True, big = True )
+
+            mapping.addGlobal( 'seg_kernel_init', kernel_init_vbase, kernel_init_size,
+                               'CXW_', vtype = 'ELF', x = x , y = y , pseg = 'RAM',
+                               binpath = 'build/kernel/kernel.elf', 
+                               local = True, big = True )
+
+    ### global vseg kernel_data: non local / big page
+    ### Only mapped in cluster[0][0]
+    mapping.addGlobal( 'seg_kernel_data', kernel_data_vbase, kernel_data_size, 
+                       'CXW_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM', 
+                       binpath = 'build/kernel/kernel.elf', 
+                       local = False, big = True )
+
+    ### global vseg kernel_uncdata: non local / small page
+    ### Only mapped in cluster[0][0]
     mapping.addGlobal( 'seg_kernel_uncdata', kernel_uncdata_vbase, kernel_uncdata_size,
-                       '__W_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM',
-                       binpath = 'build/kernel/kernel.elf', local = False )
-
-    ### global vsegs for external peripherals / identity mapping
-
+                       '__W_', vtype = 'ELF', x = 0, y = 0, pseg = 'RAM', 
+                       binpath = 'build/kernel/kernel.elf', 
+                       local = False, big = False )
+
+    ### Global vsegs kernel_ptab_x_y: non local / big pages
+    ### replicated in all clusters with name indexed by (x,y) 
+    ### as vbase address is incremented by (cluster_xy * vseg_increment)
+    for x in xrange( x_size ):
+        for y in xrange( y_size ):
+            offset = ((x << y_width) + y) * ptab_increment
+            mapping.addGlobal( 'seg_kernel_ptab_%d_%d' %(x,y), kernel_ptab_vbase + offset , kernel_ptab_size,
+                               'CXW_', vtype = 'PTAB', x = x, y = y, pseg = 'RAM', 
+                               local = False , big = True )
+
+    ### global vsegs kernel_sched : non local / small pages 
+    ### allocated in all clusters with name indexed by (x,y) 
+    ### as vbase address is incremented by (cluster_xy * vseg_increment)
+    for x in xrange( x_size ):
+        for y in xrange( y_size ):
+            offset = ((x << y_width) + y) * sched_increment
+            mapping.addGlobal( 'seg_kernel_sched_%d_%d' %(x,y), kernel_sched_vbase + offset , kernel_sched_size,
+                               'C_W_', vtype = 'SCHED', x = x , y = y , pseg = 'RAM',
+                               local = False, big = False )
+
+    ### global vsegs for external peripherals : non local / big page
     mapping.addGlobal( 'seg_iob', iob_base, iob_size, '__W_',
                        vtype = 'PERI', x = 0, y = 0, pseg = 'IOB',
-                       identity = True )
+                       local = False, big = True )
 
     mapping.addGlobal( 'seg_bdv', bdv_base, bdv_size, '__W_',
                        vtype = 'PERI', x = 0, y = 0, pseg = 'BDV',
-                       identity = True )
+                       local = False, big = True )
 
     mapping.addGlobal( 'seg_tty', tty_base, tty_size, '__W_',
                        vtype = 'PERI', x = 0, y = 0, pseg = 'TTY',
-                       identity = True )
+                       local = False, big = True )
 
     mapping.addGlobal( 'seg_nic', nic_base, nic_size, '__W_',
                        vtype = 'PERI', x = 0, y = 0, pseg = 'NIC',
-                       identity = True )
+                       local = False, big = True )
 
     mapping.addGlobal( 'seg_cma', cma_base, cma_size, '__W_',
                        vtype = 'PERI', x = 0, y = 0, pseg = 'CMA',
-                       identity = True )
+                       local = False, big = True )
 
     mapping.addGlobal( 'seg_fbf', fbf_base, fbf_size, '__W_',
                        vtype = 'PERI', x = 0, y = 0, pseg = 'FBF',
-                       identity = True )
+                       local = False, big = True )
 
     mapping.addGlobal( 'seg_pic', pic_base, pic_size, '__W_',
                        vtype = 'PERI', x = 0, y = 0, pseg = 'PIC',
-                       identity = True )
+                       local = False, big = True )
 
     mapping.addGlobal( 'seg_rom', rom_base, rom_size, 'CXW_',
                        vtype = 'PERI', x = 0, y = 0, pseg = 'ROM',
-                       identity = True )
-
-    ### global vsegs for internal peripherals, and for schedulers
-    ### name is indexed by (x,y) / vbase address is incremented by (cluster_xy * peri_increment)
-
+                       local = False, big = True )
+
+    ### global vsegs for internal peripherals : non local / small pages   
+    ### allocated in all clusters with name indexed by (x,y) 
+    ### as vbase address is incremented by (cluster_xy * vseg_increment)
     for x in xrange( x_size ):
         for y in xrange( y_size ):
-            cluster_xy = (x << y_width) + y;
-            offset     = cluster_xy * peri_increment
+            offset = ((x << y_width) + y) * peri_increment
 
             mapping.addGlobal( 'seg_xcu_%d_%d' %(x,y), xcu_base + offset, xcu_size,
-                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'XCU' )
+                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'XCU',
+                               local = False, big = False )
 
             mapping.addGlobal( 'seg_dma_%d_%d' %(x,y), dma_base + offset, dma_size,
-                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'DMA' )
+                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'DMA',
+                               local = False, big = False )
 
             mapping.addGlobal( 'seg_mmc_%d_%d' %(x,y), mmc_base + offset, mmc_size,
-                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'MMC' )
-
-            mapping.addGlobal( 'seg_sched_%d_%d' %(x,y), kernel_sched_vbase + offset, kernel_sched_size,
-                               'C_W_', vtype = 'SCHED', x = x , y = y , pseg = 'RAM' )
+                               '__W_', vtype = 'PERI' , x = x , y = y , pseg = 'MMC',
+                               local = False, big = False )
 
     ### return mapping ###
Index: trunk/platforms/tsar_generic_iob/top.cpp
===================================================================
--- trunk/platforms/tsar_generic_iob/top.cpp	(revision 816)
+++ trunk/platforms/tsar_generic_iob/top.cpp	(revision 817)
@@ -1418,5 +1418,5 @@
             uint64_t ms2 = (uint64_t) t2.tv_sec  * 1000ULL +
                            (uint64_t) t2.tv_usec / 1000;
-            std::cerr << "### cycle = " << n
+            std::cerr << "### cycle = " << std::dec << n
                       << " / frequency = "
                       << (double) 1000000 / (double) (ms2 - ms1) << "Khz"
@@ -1427,11 +1427,11 @@
 
         // Monitor a specific address for one L1 cache
-        // clusters[1][1]->proc[0]->cache_monitor(0x50090ULL);
+        // clusters[0][0]->proc[0]->cache_monitor(0xC0180ULL);
 
         // Monitor a specific address for one L2 cache
-        // clusters[0][0]->memc->cache_monitor( 0x1c4924LL, true );   // single word
+        // clusters[0][0]->memc->cache_monitor( 0xC0100ULL, true );   // single word
 
         // Monitor a specific address for one XRAM
-        // clusters[0][0]->xram->start_monitor( 0xE1900ULL , 64);
+        // clusters[0][0]->xram->start_monitor( 0xC0100ULL , 4);
 
         if ( debug_ok and (n > debug_from) )
