Index: trunk/tools/arch_info/arch_classes.py
===================================================================
--- trunk/tools/arch_info/arch_classes.py	(revision 1)
+++ trunk/tools/arch_info/arch_classes.py	(revision 6)
@@ -13,5 +13,5 @@
 #  It handle 4 types of objects: clusters, cores, devices and irqs.
 #  - The number of cluster is variable (can be one). 
-#  - The cluster topology can be a 2D mesh or a simpla array.
+#  - The cluster topology can be a 2D mesh or a simple 1D array.
 #  - The number of cores per cluster is variable (can be zero). 
 #  - The number of addressable devices per cluster is variable.
@@ -41,53 +41,43 @@
 #########################################################################################
 # These arrays define the supported types of peripherals.
-# They must be kept consistent with values defined in file arch_info.h.
+# They must be kept consistent with values defined in files arch_info.h & device.h.
 #########################################################################################
 
 DEVICE_TYPES_STR = [
-    'RAM',             # 0
-    'DMA',             # 1
-    'FBF',             # 1
-    'IOB',             # 3
-    'IOC_BDV',         # 4
-    'IOC_HBA',         # 5
-    'IOC_SDC',         # 6
-    'IOC_SPI',         # 7
-    'IOC_RDK',         # 8
-    'MMC',             # 9
-    'MWR_CPY',         # 10
-    'MWR_GCD',         # 11
-    'MWR_DCT',         # 12
-    'NIC',             # 13
-    'ROM',             # 14
-    'SIM',             # 15
-    'TIM',             # 16
-    'TTY',             # 17
-    'XCU',             # 18
-    'PIC',             # 19
-    'CMA',             # 20
+    'RAM_SCL',         # 0.0
+    'ROM_SCL',         # 1.0
+    'FBF_SCL',         # 2.0
+    'IOB_TSR',         # 3.0
+    'IOC_BDV',         # 4.0
+    'IOC_HBA',         # 4.1
+    'IOC_SDC',         # 4.2
+    'IOC_SPI',         # 4.3
+    'IOC_RDK',         # 4.4
+    'MMC_TSR',         # 5.0
+    'DMA_SCL',         # 6.0
+    'NIC_CBF',         # 7.0
+    'TIM_SCL',         # 8.0
+    'TXT_TTY',         # 9.0
+    'ICU_XCU',         # A.0
+    'PIC_TSR',         # B.0
     ]
    
 DEVICE_TYPES_INT = [
-    0x00000000,        # 0
-    0x00010000,        # 1
-    0x00020000,        # 1
-    0x00030000,        # 3
-    0x00040000,        # 4
-    0x00040001,        # 5
-    0x00040002,        # 6
-    0x00040003,        # 7
-    0x00040004,        # 8
-    0x00050000,        # 9
-    0x00060000,        # 10
-    0x00060001,        # 11
-    0x00060002,        # 12
-    0x00070000,        # 13
-    0x00080000,        # 14
-    0x00090000,        # 15
-    0x000A0000,        # 16
-    0x000B0000,        # 17
-    0x000C0000,        # 18
-    0x000D0000,        # 19
-    0x000E0000,        # 20
+    0x00000000,        # 0.0
+    0x00010000,        # 1.0
+    0x00020000,        # 1.0
+    0x00030000,        # 3.0
+    0x00040000,        # 4.0
+    0x00040001,        # 4.1
+    0x00040002,        # 4.2
+    0x00040003,        # 4.3
+    0x00040004,        # 4.4
+    0x00050000,        # 5.0
+    0x00060000,        # 6.0
+    0x00070000,        # 7.0
+    0x00080000,        # 8.0
+    0x00090000,        # 9.0
+    0x000A0000,        # A.0
+    0x000B0000,        # B.0
     ]
 
@@ -104,5 +94,5 @@
                   x_width,           # number of bits for x coordinate
                   y_width,           # number of bits for y coordinate
-                  irqs_per_core,     # number or IRQs from XCU to one core 
+                  irqs_per_core,     # number or IRQs from ICU to one core 
                   io_cxy,            # IO cluster identifier
                   boot_cxy,          # boot cluster identifier
@@ -186,5 +176,5 @@
     ################################   add an input IRQ in a device
     def addIrq( self,
-                dstdev,                # destination device (PIC or XCU)
+                dstdev,                # destination device (PIC or ICU)
                 port,                  # input IRQ port index
                 srcdev,                # source device
@@ -192,5 +182,5 @@
                 is_rx = False ):       # I/O operation direction
 
-        assert (dstdev.ptype == 'XCU') or (dstdev.ptype == 'PIC')
+        assert (dstdev.ptype == 'ICU_XCU') or (dstdev.ptype == 'PIC_TSR')
         assert (port < dstdev.arg0)
 
@@ -382,13 +372,8 @@
         ram_size     = 0
 
-        nb_cma       = 0
-        cma_channels = 0
-        cma_base     = 0xFFFFFFFFFFFFFFFF
-        cma_size     = 0
-
-        nb_dma       = 0
-        dma_channels = 0
-        dma_base     = 0xFFFFFFFFFFFFFFFF
-        dma_size     = 0
+        nb_rom       = 0
+        rom_channels = 0
+        rom_base     = 0xFFFFFFFFFFFFFFFF
+        rom_size     = 0
 
         nb_fbf       = 0
@@ -419,15 +404,8 @@
         mmc_size     = 0
 
-        nb_mwr       = 0
-        mwr_channels = 0
-        mwr_base     = 0xFFFFFFFFFFFFFFFF
-        mwr_size     = 0
-        mwr_arg0     = 0
-        mwr_arg1     = 0
-        mwr_arg2     = 0
-        mwr_arg3     = 0
-        use_mwr_gcd  = False
-        use_mwr_dct  = False
-        use_mwr_cpy  = False
+        nb_dma       = 0
+        dma_channels = 0
+        dma_base     = 0xFFFFFFFFFFFFFFFF
+        dma_size     = 0
 
         nb_nic       = 0
@@ -436,4 +414,25 @@
         nic_size     = 0
 
+        nb_sim       = 0
+        sim_channels = 0
+        sim_base     = 0xFFFFFFFFFFFFFFFF
+        sim_size     = 0
+
+        nb_tim       = 0
+        tim_channels = 0
+        tim_base     = 0xFFFFFFFFFFFFFFFF
+        tim_size     = 0
+
+        nb_txt       = 0
+        txt_channels = 0
+        txt_base     = 0xFFFFFFFFFFFFFFFF
+        txt_size     = 0
+
+        nb_icu       = 0
+        icu_channels = 0
+        icu_base     = 0xFFFFFFFFFFFFFFFF
+        icu_size     = 0
+        icu_arg0     = 0
+
         nb_pic       = 0
         pic_channels = 0
@@ -441,34 +440,8 @@
         pic_size     = 0
 
-        nb_rom       = 0
-        rom_channels = 0
-        rom_base     = 0xFFFFFFFFFFFFFFFF
-        rom_size     = 0
-
-        nb_sim       = 0
-        sim_channels = 0
-        sim_base     = 0xFFFFFFFFFFFFFFFF
-        sim_size     = 0
-
-        nb_tim       = 0
-        tim_channels = 0
-        tim_base     = 0xFFFFFFFFFFFFFFFF
-        tim_size     = 0
-
-        nb_tty       = 0
-        tty_channels = 0
-        tty_base     = 0xFFFFFFFFFFFFFFFF
-        tty_size     = 0
-
-        nb_xcu       = 0
-        xcu_channels = 0
-        xcu_base     = 0xFFFFFFFFFFFFFFFF
-        xcu_size     = 0
-        xcu_arg0     = 0
-
-        nb_drom       = 0
-        drom_channels = 0
-        drom_base     = 0xFFFFFFFFFFFFFFFF
-        drom_size     = 0
+        nb_rom        = 0
+        rom_channels  = 0
+        rom_base      = 0xFFFFFFFFFFFFFFFF
+        rom_size      = 0
 
         # get devices attributes
@@ -476,5 +449,5 @@
             for device in cluster.devices:
 
-                if ( device.ptype == 'RAM' ):
+                if ( device.ptype == 'RAM_SCL' ):
                     ram_base     = device.base
                     ram_size     = device.size
@@ -482,17 +455,11 @@
                     nb_ram +=1
                 
-                elif ( device.ptype == 'CMA' ):
-                    cma_base     = device.base
-                    cma_size     = device.size
-                    cma_channels = device.channels
-                    nb_cma +=1
-
-                elif ( device.ptype == 'DMA' ):
-                    dma_base     = device.base
-                    dma_size     = device.size
-                    dma_channels = device.channels
-                    nb_dma +=1
-
-                elif ( device.ptype == 'FBF' ):
+                elif ( device.ptype == 'ROM_SCL' ):
+                    rom_base     = device.base
+                    rom_size     = device.size
+                    rom_channels = device.channels
+                    nb_rom +=1
+
+                elif ( device.ptype == 'FBF_SCL' ):
                     fbf_base     = device.base
                     fbf_size     = device.size
@@ -502,5 +469,5 @@
                     nb_fbf +=1
 
-                elif ( device.ptype == 'IOB' ):
+                elif ( device.ptype == 'IOB_TSR' ):
                     iob_base     = device.base
                     iob_size     = device.size
@@ -532,5 +499,4 @@
                     use_ioc_spi  = True
                     nb_ioc += 1
-
                 elif ( device.ptype == 'IOC_RDK' ):
                     ioc_base     = device.base
@@ -540,5 +506,5 @@
                     nb_ioc += 1
 
-                elif ( device.ptype == 'MMC' ):
+                elif ( device.ptype == 'MMC_TSR' ):
                     mmc_base     = device.base
                     mmc_size     = device.size
@@ -546,54 +512,11 @@
                     nb_mmc +=1
 
-                elif ( device.ptype == 'MWR_GCD' ):
-                    mwr_base     = device.base
-                    mwr_size     = device.size
-                    mwr_channels = device.channels
-                    mwr_arg0     = device.arg0
-                    mwr_arg1     = device.arg1
-                    mwr_arg2     = device.arg2
-                    mwr_arg3     = device.arg3
-                    use_mwr_gcd  = True
-                    nb_mwr +=1
-                elif ( device.ptype == 'MWR_DCT' ):
-                    mwr_base     = device.base
-                    mwr_size     = device.size
-                    mwr_channels = device.channels
-                    mwr_arg0     = device.arg0
-                    mwr_arg1     = device.arg1
-                    mwr_arg2     = device.arg2
-                    mwr_arg3     = device.arg3
-                    use_mwr_dct  = True
-                    nb_mwr +=1
-                elif ( device.ptype == 'MWR_CPY' ):
-                    mwr_base     = device.base
-                    mwr_size     = device.size
-                    mwr_channels = device.channels
-                    mwr_arg0     = device.arg0
-                    mwr_arg1     = device.arg1
-                    mwr_arg2     = device.arg2
-                    mwr_arg3     = device.arg3
-                    use_mwr_cpy  = True
-                    nb_mwr +=1
-
-                elif ( device.ptype == 'ROM' ):
-                    rom_base     = device.base
-                    rom_size     = device.size
-                    rom_channels = device.channels
-                    nb_rom +=1
-
-                elif ( device.ptype == 'DROM' ):
-                    drom_base     = device.base 
-                    drom_size     = device.size
-                    drom_channels = device.channels
-                    nb_drom +=1
-
-                elif ( device.ptype == 'SIM' ):
-                    sim_base     = device.base
-                    sim_size     = device.size
-                    sim_channels = device.channels
-                    nb_sim +=1
-
-                elif ( device.ptype == 'NIC' ):
+                elif ( device.ptype == 'DMA_SCL' ):
+                    dma_base     = device.base
+                    dma_size     = device.size
+                    dma_channels = device.channels
+                    nb_dma +=1
+
+                elif ( device.ptype == 'NIC_CBF' ):
                     nic_base     = device.base
                     nic_size     = device.size
@@ -601,39 +524,31 @@
                     nb_nic +=1
 
-                elif ( device.ptype == 'PIC' ):
+                elif ( device.ptype == 'TIM_SCL' ):
+                    tim_base     = device.pseg.base
+                    tim_size     = device.pseg.size
+                    tim_channels = device.channels
+                    nb_tim +=1
+
+                elif ( device.ptype == 'TXT_TTY' ):
+                    txt_base     = device.base
+                    txt_size     = device.size
+                    txt_channels = device.channels
+                    nb_txt +=1
+
+                elif ( device.ptype == 'ICU_XCU' ):
+                    icu_base     = device.base
+                    icu_size     = device.size
+                    icu_channels = device.channels
+                    icu_arg0     = device.arg0
+                    icu_arg1     = device.arg1
+                    icu_arg2     = device.arg2
+                    icu_arg3     = device.arg3
+                    nb_icu +=1
+
+                elif ( device.ptype == 'PIC_TSR' ):
                     pic_base     = device.base
                     pic_size     = device.size
                     pic_channels = device.channels
                     nb_pic +=1
-
-                elif ( device.ptype == 'TIM' ):
-                    tim_base     = device.pseg.base
-                    tim_size     = device.pseg.size
-                    tim_channels = device.channels
-                    nb_tim +=1
-
-                elif ( device.ptype == 'TTY' ):
-                    tty_base     = device.base
-                    tty_size     = device.size
-                    tty_channels = device.channels
-                    nb_tty +=1
-
-                elif ( device.ptype == 'XCU' ):
-                    xcu_base     = device.base
-                    xcu_size     = device.size
-                    xcu_channels = device.channels
-                    xcu_arg0     = device.arg0
-                    xcu_arg1     = device.arg1
-                    xcu_arg2     = device.arg2
-                    nb_xcu +=1
-
-        # no more than two access to external devices
-        assert ( nb_fbf <= 2 )
-        assert ( nb_cma <= 2 )
-        assert ( nb_ioc <= 2 )
-        assert ( nb_nic <= 2 )
-        assert ( nb_tim <= 2 )
-        assert ( nb_tty <= 2 )
-        assert ( nb_pic <= 2 )
 
         # one and only one IOC controller
@@ -647,11 +562,4 @@
             rdk_base = 0
             rdk_size = 0
-
-        # only one type of MWR controller
-        nb_mwr_types = 0
-        if use_mwr_gcd:       nb_mwr_types += 1
-        if use_mwr_dct:       nb_mwr_types += 1
-        if use_mwr_cpy:       nb_mwr_types += 1
-        if ( nb_mwr > 0 ) : assert ( nb_mwr_types == 1 )
 
         # Compute total number of cores, devices and irqs
@@ -697,18 +605,15 @@
         s += '/* Peripherals */\n'
         s += '\n'
-        s += '#define NB_TTY_CHANNELS        %d\n'    % tty_channels
+        s += '#define NB_TXT_CHANNELS        %d\n'    % txt_channels
         s += '#define NB_IOC_CHANNELS        %d\n'    % ioc_channels
         s += '#define NB_NIC_CHANNELS        %d\n'    % nic_channels
-        s += '#define NB_CMA_CHANNELS        %d\n'    % cma_channels
         s += '#define NB_TIM_CHANNELS        %d\n'    % tim_channels
-        s += '#define NB_DMA_CHANNELS        %d\n'    % dma_channels
-        s += '\n'
-        s += '#define USE_XCU                %d\n'    % ( nb_xcu != 0 )
-        s += '#define USE_DMA                %d\n'    % ( nb_dma != 0 )
-        s += '\n'
+        s += '\n'
+        s += '#define USE_ICU                %d\n'    % ( nb_icu != 0 )
         s += '#define USE_IOB                %d\n'    % ( nb_iob != 0 )
         s += '#define USE_PIC                %d\n'    % ( nb_pic != 0 )
         s += '#define USE_FBF                %d\n'    % ( nb_fbf != 0 )
         s += '#define USE_NIC                %d\n'    % ( nb_nic != 0 )
+        s += '#define USE_DMA                %d\n'    % ( nb_dma != 0 )
         s += '\n'
         s += '#define USE_IOC_BDV            %d\n'    % use_ioc_bdv
@@ -718,20 +623,11 @@
         s += '#define USE_IOC_RDK            %d\n'    % use_ioc_rdk
         s += '\n'
-        s += '#define USE_MWR_GCD            %d\n'    % use_mwr_gcd
-        s += '#define USE_MWR_DCT            %d\n'    % use_mwr_dct
-        s += '#define USE_MWR_CPY            %d\n'    % use_mwr_cpy
-        s += '\n'
         s += '#define FBUF_X_SIZE            %d\n'    % fbf_arg0
         s += '#define FBUF_Y_SIZE            %d\n'    % fbf_arg1
         s += '\n'
-        s += '#define XCU_NB_HWI             %d\n'    % xcu_arg0
-        s += '#define XCU_NB_PTI             %d\n'    % xcu_arg1
-        s += '#define XCU_NB_WTI             %d\n'    % xcu_arg2
-        s += '#define XCU_NB_OUT             %d\n'    % xcu_channels
-        s += '\n'
-        s += '#define MWR_TO_COPROC          %d\n'    % mwr_arg0
-        s += '#define MWR_FROM_COPROC        %d\n'    % mwr_arg1
-        s += '#define MWR_CONFIG             %d\n'    % mwr_arg2
-        s += '#define MWR_STATUS             %d\n'    % mwr_arg3
+        s += '#define ICU_NB_HWI             %d\n'    % icu_arg0
+        s += '#define ICU_NB_PTI             %d\n'    % icu_arg1
+        s += '#define ICU_NB_WTI             %d\n'    % icu_arg2
+        s += '#define ICU_NB_OUT             %d\n'    % icu_arg3
         s += '\n'
 
@@ -741,25 +637,19 @@
         s += '#define SEG_RAM_SIZE           0x%x\n'  % ram_size
         s += '\n'
-        s += '#define SEG_CMA_BASE           0x%x\n'  % (cma_base & local_physical_mask)
-        s += '#define SEG_CMA_SIZE           0x%x\n'  % cma_size
+        s += '#define SEG_FBF_BASE           0x%x\n'  % (fbf_base & local_physical_mask)
+        s += '#define SEG_FBF_SIZE           0x%x\n'  % fbf_size
+        s += '\n'
+        s += '#define SEG_IOB_BASE           0x%x\n'  % (iob_base & local_physical_mask)
+        s += '#define SEG_IOB_SIZE           0x%x\n'  % iob_size
+        s += '\n'
+        s += '#define SEG_IOC_BASE           0x%x\n'  % (ioc_base & local_physical_mask)
+        s += '#define SEG_IOC_SIZE           0x%x\n'  % ioc_size
+        s += '\n'
+        s += '#define SEG_MMC_BASE           0x%x\n'  % (mmc_base & local_physical_mask)
+        s += '#define SEG_MMC_SIZE           0x%x\n'  % mmc_size
         s += '\n'
         s += '#define SEG_DMA_BASE           0x%x\n'  % (dma_base & local_physical_mask)
         s += '#define SEG_DMA_SIZE           0x%x\n'  % dma_size
         s += '\n'
-        s += '#define SEG_FBF_BASE           0x%x\n'  % (fbf_base & local_physical_mask)
-        s += '#define SEG_FBF_SIZE           0x%x\n'  % fbf_size
-        s += '\n'
-        s += '#define SEG_IOB_BASE           0x%x\n'  % (iob_base & local_physical_mask)
-        s += '#define SEG_IOB_SIZE           0x%x\n'  % iob_size
-        s += '\n'
-        s += '#define SEG_IOC_BASE           0x%x\n'  % (ioc_base & local_physical_mask)
-        s += '#define SEG_IOC_SIZE           0x%x\n'  % ioc_size
-        s += '\n'
-        s += '#define SEG_MMC_BASE           0x%x\n'  % (mmc_base & local_physical_mask)
-        s += '#define SEG_MMC_SIZE           0x%x\n'  % mmc_size
-        s += '\n'
-        s += '#define SEG_MWR_BASE           0x%x\n'  % (mwr_base & local_physical_mask)
-        s += '#define SEG_MWR_SIZE           0x%x\n'  % mwr_size
-        s += '\n'
         s += '#define SEG_ROM_BASE           0x%x\n'  % (rom_base & local_physical_mask)
         s += '#define SEG_ROM_SIZE           0x%x\n'  % rom_size
@@ -777,15 +667,12 @@
         s += '#define SEG_TIM_SIZE           0x%x\n'  % tim_size
         s += '\n'
-        s += '#define SEG_TTY_BASE           0x%x\n'  % (tty_base & local_physical_mask)
-        s += '#define SEG_TTY_SIZE           0x%x\n'  % tty_size
-        s += '\n'
-        s += '#define SEG_XCU_BASE           0x%x\n'  % (xcu_base & local_physical_mask)
-        s += '#define SEG_XCU_SIZE           0x%x\n'  % xcu_size
+        s += '#define SEG_TXT_BASE           0x%x\n'  % (txt_base & local_physical_mask)
+        s += '#define SEG_TXT_SIZE           0x%x\n'  % txt_size
+        s += '\n'
+        s += '#define SEG_ICU_BASE           0x%x\n'  % (icu_base & local_physical_mask)
+        s += '#define SEG_ICU_SIZE           0x%x\n'  % icu_size
         s += '\n'
         s += '#define SEG_RDK_BASE           0x%x\n'  % (rdk_base & local_physical_mask)
         s += '#define SEG_RDK_SIZE           0x%x\n'  % rdk_size
-        s += '\n'
-        s += '#define SEG_DROM_BASE          0x%x\n'  % (drom_base & local_physical_mask)
-        s += '#define SEG_DROM_SIZE          0x%x\n'  % drom_size
         s += '\n'
         s += '#endif\n'
@@ -931,5 +818,5 @@
         self.arg2     = arg2          # optional (semantic depends on ptype)
         self.arg3     = arg3          # optional (semantic depends on ptype)
-        self.irqs     = []            # set of input IRQs (for PIC and XCU only)
+        self.irqs     = []            # set of input IRQs (for PIC and ICU only)
         self.irq_ctrl = None          # interrupt controller for this device
         return
@@ -946,5 +833,5 @@
         s += ' arg2="%d"'                    % self.arg2
         s += ' arg3="%d"'                    % self.arg3
-        if ( (self.ptype == 'PIC') or (self.ptype == 'XCU') ):
+        if ( (self.ptype == 'PIC_TSR') or (self.ptype == 'ICU_XCU') ):
             s += ' >\n'
             for irq in self.irqs: s += irq.xml()
@@ -958,6 +845,6 @@
 
         if ( verbose ):
-            print '*** cbin for device[%d] / type %s' \
-                  % (self.index , self.ptype)
+            print '*** cbin for device[%d] / type = %s / base = %x' \
+                  % (self.index , self.ptype , self.base)
 
         # check index
@@ -985,7 +872,7 @@
 
         byte_stream = bytearray()
-        byte_stream += mapping.int2bytes(4,ptype_id)       # device type
         byte_stream += mapping.int2bytes(8,self.base)      # segment base address
         byte_stream += mapping.int2bytes(8,self.size)      # segment size
+        byte_stream += mapping.int2bytes(4,ptype_id)       # device type
         byte_stream += mapping.int2bytes(4,self.channels)  # number of channels
         byte_stream += mapping.int2bytes(4,self.arg0)      # optionnal arg0
@@ -997,5 +884,4 @@
 
         if ( verbose ):
-            print 'ptype      = %d' %  ptype_id
             print 'base       = %x' %  self.base
             print 'size       = %x' %  self.size
@@ -1034,6 +920,6 @@
 
         if ( verbose ):
-            print '*** cbin for irq[%d] / type = %s' \
-                   % (self.index , self.isrtype)
+            print '*** cbin for irq[%d] / src_dev = %s' \
+                   % (self.port , self.dev.ptype)
 
         # check index
@@ -1041,5 +927,5 @@
             print '[genarch error] in Irq.cbin()'
             print '    irq global index = %d / expected = %d' \
-                       % (self.index,expected)
+                       % (self.index , expected)
             sys.exit(1)
 
Index: trunk/tools/arch_info/arch_info.h
===================================================================
--- trunk/tools/arch_info/arch_info.h	(revision 1)
+++ trunk/tools/arch_info/arch_info.h	(revision 6)
@@ -63,13 +63,13 @@
  * The 16 MSB bits define the functionnal type.
  * The 16 LSB bits define the implementation type.
- * It must be consistent with values defined in file arch_class.py
+ * It must be consistent with values defined in files arch_class.py, and device.*
  ***************************************************************************************/
 
 enum deviceTypes
 {
-    DEV_TYPE_RAM       = 0x00000000,
-    DEV_TYPE_DMA       = 0x00010000,
-    DEV_TYPE_FBF       = 0x00020000,
-    DEV_TYPE_IOB       = 0x00030000,
+    DEV_TYPE_RAM_SCL   = 0x00000000,
+    DEV_TYPE_ROM_SCL   = 0x00010000,
+    DEV_TYPE_FBF_SCL   = 0x00020000,
+    DEV_TYPE_IOB_TSR   = 0x00030000,
     DEV_TYPE_IOC_BDV   = 0x00040000,
     DEV_TYPE_IOC_HBA   = 0x00040001,
@@ -77,16 +77,11 @@
     DEV_TYPE_IOC_SPI   = 0x00040003,
     DEV_TYPE_IOC_RDK   = 0x00040004,
-    DEV_TYPE_MMC       = 0x00050000,
-    DEV_TYPE_MWR_CPY   = 0x00060000,
-    DEV_TYPE_MWR_GCD   = 0x00060001,
-    DEV_TYPE_MWR_DCT   = 0x00060002,
-    DEV_TYPE_NIC       = 0x00070000,
-    DEV_TYPE_ROM       = 0x00080000,
-    DEV_TYPE_SIM       = 0x00090000,
-    DEV_TYPE_TIM       = 0x000A0000,
-    DEV_TYPE_TTY       = 0x000B0000,
-    DEV_TYPE_XCU       = 0x000C0000,
-    DEV_TYPE_PIC       = 0x000D0000,
-    DEV_TYPE_CMA       = 0x000E0000,
+    DEV_TYPE_MMC_TSR   = 0x00050000,
+    DEV_TYPE_DMA_SCL   = 0x00060000,
+    DEV_TYPE_NIC_CBF   = 0x00070000,
+    DEV_TYPE_TIM_SCL   = 0x00080000,
+    DEV_TYPE_TXT_TTY   = 0x00090000,
+    DEV_TYPE_ICU_XCU   = 0x000A0000,
+    DEV_TYPE_PIC_TSR   = 0x000B0000,
 };
 
@@ -143,6 +138,6 @@
 {
     uint32_t    gid;             // core hardware identifier
+    uint16_t    cxy;             // cluster identifier         
     uint16_t    lid;             // core local index in cluster
-    uint16_t    cxy;             // cluster identifier         
 } 
 archinfo_core_t;
@@ -154,7 +149,7 @@
 typedef struct __attribute__((packed))  archinfo_device_s
 {
+    uint64_t    base;            // base address in physical space
+    uint64_t    size;            // channel size (bytes)
     uint32_t    type;            // supported values defined above
-    uint64_t    base;            // base address in physical space
-    uint64_t    size;            // size (bytes)
     uint32_t    channels;        // number of channels
     uint32_t    arg0;            // semantic depends on device type
@@ -162,5 +157,5 @@
     uint32_t    arg2;            // semantic depends on device type
     uint32_t    arg3;            // semantic depends on device type
-    uint32_t    irqs;            // number of input IRQs (for XCU or PIC)
+    uint32_t    irqs;            // number of input IRQs (for ICU or PIC)
     uint32_t    irq_offset;      // global index of first IRQ 
 } 
Index: trunk/tools/arch_info/boot_info.h
===================================================================
--- trunk/tools/arch_info/boot_info.h	(revision 1)
+++ trunk/tools/arch_info/boot_info.h	(revision 6)
@@ -32,5 +32,5 @@
  ********************************************************************************************/
 
-#define BOOT_INFO_SIGNATURE    0xBABEF00D
+#define BOOT_INFO_SIGNATURE    0x12344321
 
 /*********************************************************************************************
@@ -69,7 +69,7 @@
 typedef struct boot_device_s
 {
+    uint64_t    base;                 /*! segment physical base address                     */
+    uint64_t    size;                 /*! channel size (bytes)                              */
     uint32_t    type;                 /*! peripheral type (func | impl)                     */
-    xptr_t      base;                 /*! segment global base address                       */
-    uint64_t    size;                 /*! channel size (bytes)                              */
     uint32_t    channels;             /*! number of channels                                */
     uint32_t    param0;               /*! semantic depends on peripherat type               */
@@ -90,31 +90,36 @@
 typedef struct boot_info_s
 {
-    uint32_t      signature;         /*! boot info signature                                */
+    uint32_t      signature;                     /*! boot info signature                    */
 
     // global platform parameters
 
-	uint32_t      paddr_width;        /*! number of bits in physical address                */
-    uint32_t      x_width;            /*! number of bits to code X coordinate               */
-    uint32_t      y_width;            /*! number of bits to code Y coordinate               */
-	uint32_t      x_size;             /*! number of cluster in a row                        */
-	uint32_t      y_size;             /*! number of cluster in a column                     */
-	uint32_t      io_cxy;             /*! IO cluster identifier                             */
+	uint32_t      paddr_width;                   /*! number of bits in physical address     */
+    uint32_t      x_width;                       /*! number of bits to code X coordinate    */
+    uint32_t      y_width;                       /*! number of bits to code Y coordinate    */
+	uint32_t      x_size;                        /*! number of cluster in a row             */
+	uint32_t      y_size;                        /*! number of cluster in a column          */
+	uint32_t      io_cxy;                        /*! IO cluster identifier                  */
 
-    // specific cluster parameters
+    // shared resources
 
-	uint32_t      cxy;                /*! current cluster identifier                        */
-	uint32_t      cores_nr;           /*! number of cores in current cluster                */
-    boot_core_t   core[CONFIG_MAX_CORES_PER_CLUSTER];   /* array of core descriptors        */  
-	uint32_t      devices_nr;         /*! number of peripherals in current cluster          */
-    boot_device_t dev[CONFIG_MAX_DEVICES_PER_CLUSTER];  /* array of device descriptors      */
-    uint32_t      pages_nr;           /*! total number of 4 Kbytes pages in cluster         */
-    uint32_t      pages_offset;       /*! number of pages already allocated for kernel      */
+    uint32_t      ext_dev_nr;                    /*! number of external peripherals         */
+    boot_device_t ext_dev[CONFIG_MAX_EXT_DEV];   /*! array of external peripherals          */
+
+    // private resources (per cluster)
+
+	uint32_t      cxy;                           /*! cluster identifier                     */
+	uint32_t      cores_nr;                      /*! number of local cores in               */
+    boot_core_t   core[CONFIG_MAX_LOCAL_CORES];  /*! array of core descriptors              */  
+	uint32_t      int_dev_nr;                    /*! number of local peripherals            */
+    boot_device_t int_dev[CONFIG_MAX_INT_DEV];   /*! array of internal peripherals          */
+    uint32_t      pages_nr;                      /*! number of 4 Kbytes pages               */
+    uint32_t      pages_offset;                  /*! number of pages allocated for kernel   */
 
     // kernel segments
 
-    intptr_t      kernel_code_start;  /*! kernel code base address                          */
-    intptr_t      kernel_code_end;    /*! kernel code last address (excluded)               */
-    intptr_t      kernel_data_start;  /*! kernel data base address                          */
-    intptr_t      kernel_data_end;    /*! kernel data last address (excluded)               */
+    intptr_t      kernel_code_start;             /*! kernel code base address               */
+    intptr_t      kernel_code_end;               /*! kernel code last address (excluded)    */
+    intptr_t      kernel_data_start;             /*! kernel data base address               */
+    intptr_t      kernel_data_end;               /*! kernel data last address (excluded)    */
 }
 boot_info_t;
Index: trunk/tools/arch_info/genarch.py
===================================================================
--- trunk/tools/arch_info/genarch.py	(revision 1)
+++ trunk/tools/arch_info/genarch.py	(revision 6)
@@ -23,8 +23,6 @@
 #  --nb_ttys=int     : number of TTY channels 
 #  --nb_nics=int     : number of NIC channels 
-#  --nb_cmas=int     : number of CMA channels
 #  --fbf_size=int    : frame buffer width & heigth
 #  --ioc_type=string : can be IOC_BDV , IOC_HBA , IOC_SDC , IOC_SPI
-#  --mwr_type=string : can be MWR_GCD , MWR_DCT , MWR_CPY
 #  --io_cxy=int      : IO cluster identifier
 #  --boot_cxy=int    : boot cluster identifier
@@ -76,8 +74,4 @@
                    help = 'define number ot NIC channels' )
 
-parser.add_option( '--nb_cmas', type = 'int', dest = 'nb_cmas',
-                   default = 2,
-                   help = 'define number ot CMA channels' )
-
 parser.add_option( '--fbf_size', type = 'int', dest = 'fbf_size', 
                    default = 128,
@@ -87,8 +81,4 @@
                    default = 'IOC_BDV',
                    help = 'define type of IOC: BDV / HBA / SDC / RDK / SPI' )
-
-parser.add_option( '--mwr_type', type = 'string', dest = 'mwr_type',
-                   default = 'MWR_CPY',
-                   help = 'define type of COPROC: CPY / DCT / GCD' )
 
 parser.add_option( '--io_cxy', type = 'int', dest = 'io_cxy',
@@ -129,7 +119,5 @@
 fbf_size       = options.fbf_size    # frame buffer width & heigth
 nb_nics        = options.nb_nics     # number of NIC channels           
-nb_cmas        = options.nb_cmas     # number of CMA channels           
 ioc_type       = options.ioc_type    # ioc controller type
-mwr_type       = options.mwr_type    # hardware coprocessor type
 io_cxy         = options.io_cxy      # IO cluster identifier 
 boot_cxy       = options.boot_cxy    # boot cluster identifier 
@@ -163,8 +151,6 @@
                         nb_ttys, 
                         nb_nics, 
-                        nb_cmas, 
                         fbf_size, 
                         ioc_type, 
-                        mwr_type,
                         io_cxy,
                         boot_cxy,
Index: trunk/tools/bootloader_tsar/boot.c
===================================================================
--- trunk/tools/bootloader_tsar/boot.c	(revision 1)
+++ trunk/tools/bootloader_tsar/boot.c	(revision 6)
@@ -1,4 +1,27 @@
+/*
+ * boot.c - TSAR bootloader implementation.
+ * 
+ * Authors :   Alain Greiner / Vu Son  (2016)
+ *
+ * Copyright (c) UPMC Sorbonne Universites
+ *
+ * This file is part of ALMOS-MKH.
+ *
+ * ALMOS-MKH is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.0 of the License.
+ *
+ * ALMOS-MKH is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ALMOS-MKH; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
 /****************************************************************************
- * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture.  *
+ * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture. *
  *                                                                          *
  * It supports clusterised shared memory multi-processor architectures,     *
@@ -47,4 +70,5 @@
 
 #include <elf-types.h>
+#include <hal_types.h>
 
 #include <almos_config.h>
@@ -53,6 +77,4 @@
 #include <arch_info.h>
 #include <boot_info.h>
-
-#include <hal_types.h>
 
 #include <boot_utils.h>
@@ -62,6 +84,6 @@
 #include <boot_tty_driver.h>
 
-/****************************************************************************
- *                                 Macros.                                  *
+/*****************************************************************************
+ *                                 Macros.                              
  ****************************************************************************/
 
@@ -70,43 +92,36 @@
                             (~(PPM_PAGE_SIZE-1)))
 
-/****************************************************************************
- *                             Global variables.                            *
+/*****************************************************************************
+ *                             Global variables.                            
  ****************************************************************************/
 
 // synchronization variables. 
-volatile boot_barrier_t global_barrier;     /* Used by bscpu to synchronize 
-                                               with other CP0s cores.       */
-
-volatile uint32_t   global_count;           /* Number of cores expected in 
-                                               global barrier.              */
-
-volatile uint32_t   local_barrier;          /* Used by CP0 to synchronize 
-                                               with local CPi.              */
-
-volatile uint32_t   boot_cluster_ready;     /* Modified by bscpu to report 
-                                               that the boot cluster is 
-                                               ready.                       */
-
-// kernel image memory layout. 
-uint32_t ktext_base;                        /* ktext segment base address.  */
-uint32_t ktext_end;                         /* ktext segment end address.   */
-uint32_t kdata_base;                        /* kdata segment base address.  */
-uint32_t kdata_end;                         /* kdata segment end address.   */
-
-uint32_t kernel_entry;                      /* Kernel entry point.          */
-
-// Extern variables. 
-extern void boot_entry();                   /* boot_loader() function       */
-
-/****************************************************************************
- *                           Internal functions.                            *
- ****************************************************************************/
-
+
+volatile boot_remote_spinlock_t tty0_lock;       // protect TTY0 access
+volatile boot_remote_barrier_t  global_barrier;  // synchronize CP0 cores
+volatile boot_remote_barrier_t  local_barrier;   // synchronize cores in one cluster
+uint32_t                        active_cp0s_nr;  // number of expected CP0s
+ 
+// kernel segments layout variables
+
+uint32_t                        seg_kcode_base;  // kcode segment base address
+uint32_t                        seg_kcode_size;  // kcode segment size (bytes) 
+uint32_t                        seg_kdata_base;  // kdata segment base address
+uint32_t                        seg_kdata_size;  // kdata segment size (bytes) 
+uint32_t                        kernel_entry;    // kernel entry point
+
+// address used by the WTI to activate remote CP0s
+
+extern void                     boot_entry();    // boot_loader entry point
+
+/*********************************************************************************
+ * This function returns the printable string for each device type
+ ********************************************************************************/
 char * device_type_str( uint32_t dev_type )
 {
-    if     ( dev_type == DEV_TYPE_RAM     ) return "RAM";
-    else if( dev_type == DEV_TYPE_DMA     ) return "DMA";
-    else if( dev_type == DEV_TYPE_FBF     ) return "FBF";
-    else if( dev_type == DEV_TYPE_IOB     ) return "IOB";
+    if     ( dev_type == DEV_TYPE_RAM_SCL ) return "RAM_SCL";
+    else if( dev_type == DEV_TYPE_ROM_SCL ) return "ROM_SCL";
+    else if( dev_type == DEV_TYPE_FBF_SCL ) return "FBF_SCL";
+    else if( dev_type == DEV_TYPE_IOB_TSR ) return "IOB_TSR";
     else if( dev_type == DEV_TYPE_IOC_BDV ) return "IOC_BDV";
     else if( dev_type == DEV_TYPE_IOC_HBA ) return "IOC_HBA";
@@ -114,22 +129,17 @@
     else if( dev_type == DEV_TYPE_IOC_SPI ) return "IOC_SPI";
     else if( dev_type == DEV_TYPE_IOC_RDK ) return "IOC_RDK";
-    else if( dev_type == DEV_TYPE_MMC     ) return "MMC";
-    else if( dev_type == DEV_TYPE_MWR_CPY ) return "MWR_CPY";
-    else if( dev_type == DEV_TYPE_MWR_GCD ) return "MWR_GCD";
-    else if( dev_type == DEV_TYPE_MWR_DCT ) return "MWR_DCT";
-    else if( dev_type == DEV_TYPE_NIC     ) return "NIC";
-    else if( dev_type == DEV_TYPE_ROM     ) return "ROM";
-    else if( dev_type == DEV_TYPE_SIM     ) return "SIM";
-    else if( dev_type == DEV_TYPE_TIM     ) return "TIM";
-    else if( dev_type == DEV_TYPE_TTY     ) return "TTY";
-    else if( dev_type == DEV_TYPE_XCU     ) return "XCU";
-    else if( dev_type == DEV_TYPE_PIC     ) return "PIC";
-    else if( dev_type == DEV_TYPE_CMA     ) return "CMA";
-    else                                    return "UNDEFINED";
+    else if( dev_type == DEV_TYPE_MMC_TSR ) return "MMC_TSR";
+    else if( dev_type == DEV_TYPE_DMA_SCL ) return "DMA_SCL";
+    else if( dev_type == DEV_TYPE_NIC_CBF ) return "NIC_CBF";
+    else if( dev_type == DEV_TYPE_TIM_SCL ) return "TIM_SCL";
+    else if( dev_type == DEV_TYPE_TXT_TTY ) return "TXT_TTY";
+    else if( dev_type == DEV_TYPE_ICU_XCU ) return "ICU_XCU";
+    else if( dev_type == DEV_TYPE_PIC_TSR ) return "PIC_TSR";
+    else                                    return "undefined";
 }
 
-/****************************************************************************
+/************************************************************************************
  * This function loads the arch_info.bin file into the boot cluster memory.
- ****************************************************************************/
+ ***********************************************************************************/
 static void boot_archinfo_load()
 {
@@ -154,59 +164,48 @@
 
 #if DEBUG_BOOT_INFO
-boot_printf("\n[BOOT] file %s loaded at %l\n",
-            ARCHINFO_PATHNAME , ARCHINFO_BASE );
+boot_printf("\n[BOOT INFO] in %s : file %s loaded at address = %x\n",
+            __FUNCTION__ , ARCHINFO_PATHNAME , ARCHINFO_BASE );
 #endif
 
 } // boot_archinfo_load()
 
-/****************************************************************************
- * This function loads the 'kernel.elf' file into the boot cluster memory   *
- * bank, analyzes it then places the kernel image at the temporary physical *
- * memory address KERN_IMG_TMP_BASE since other processors are still        *
- * executing the preloader code (which means that the kernel image cannot   *
- * be placed now at its final memory location starting at address 0x0.      *
- ****************************************************************************/
+/**************************************************************************************
+ * This function loads the 'kernel.elf' file into the boot cluster memory buffer,
+ * analyzes it, and places the the two seg_kcode & seg_kdata segments at their final
+ * physical adresses (just after the preloader zone).        
+ * It set the global variables defining the kernel layout.
+ *************************************************************************************/
 static void boot_kernel_load()
 {
-    Elf32_Ehdr* elf_header;         /* Pointer on 'kernel.elf' header.      */
-    Elf32_Phdr* program_header;     /* Pointer on 'kernel.elf' program 
-                                       header.                              */
-    uint32_t    phdr_offset;        /* Program header offset in 
-                                       'kernel.elf' file.                   */
-    uint32_t    segments_nb;        /* Total number of segments in 
-                                       'kernel.elf' file.                   */
-
-    uint32_t    seg_src_addr;       /* Segment address in 'kernel.elf' 
-                                       file (source).                       */
-    uint32_t    seg_paddr;          /* Physical address at which the 
-                                       first byte of the segment resides 
-                                       in memory.                           */
-    uint32_t    seg_offset;         /* Offset from the beginning of 
-                                       'kernel.elf' file to the segment's
-                                       first byte.                          */ 
-    uint32_t    seg_filesz;         /* Segment's number of bytes in 
-                                       'kernel.elf' file.                   */ 
-    uint32_t    seg_memsz;          /* Segment's number of bytes in the 
-                                       memory image.                        */
-
-    uint32_t    seg_id;             /* Iterator for program header scanning
-                                       loop.                                */
-
-    /* Loading file into memory. */
-    if (boot_fat32_load(KERNEL_PATHNAME, KERN_BASE, KERN_MAX_SIZE))
-    {
-        boot_printf("\n[BOOT ERROR]: boot_kernel_load(): "
-                    "<%s> file not found\n",
+    Elf32_Ehdr * elf_header;      // pointer on kernel.elf header.  
+    Elf32_Phdr * program_header;  // pointer on kernel.elf program header. 
+    uint32_t     phdr_offset;     // program header offset in kernel.elf file. 
+    uint32_t     segments_nb;     // number of segments in kernel.elf file. 
+    uint32_t     seg_src_addr;    // segment address in kernel.elf file (source).
+    uint32_t     seg_paddr;       // segment local physical address of segment 
+    uint32_t     seg_offset;      // segment offset in kernel.elf file
+    uint32_t     seg_filesz;      // segment size (bytes) in kernel.elf file 
+    uint32_t     seg_memsz;       // segment size (bytes) in memory image.
+    bool_t       kcode_found;     // kcode segment found.
+    bool_t       kdata_found;     // kdata segment found.
+    uint32_t     seg_id;          // iterator for segments loop.
+
+#if DEBUG_BOOT_ELF 
+boot_printf("\n[BOOT INFO] %s enters for file %s at cycle %d\n",
+            __FUNCTION__ , KERNEL_PATHNAME , boot_get_proctime() );
+#endif
+
+    // Load kernel.elf file into memory buffer
+    if ( boot_fat32_load(KERNEL_PATHNAME, KERN_BASE, KERN_MAX_SIZE) )
+    {
+        boot_printf("\n[BOOT ERROR] in %s : <%s> file not found\n",
                     KERNEL_PATHNAME);
         boot_exit();
     }
 
-    /* 
-     * Initializing pointer to header which is the first element of the 
-     * .elf file. 
-     */
+    // get pointer to kernel.elf header  
     elf_header = (Elf32_Ehdr*)KERN_BASE;
 
-    /* Signature problem, abort program !!! */
+    // check signature 
     if ((elf_header->e_ident[EI_MAG0] != ELFMAG0)   ||
         (elf_header->e_ident[EI_MAG1] != ELFMAG1)   ||
@@ -220,18 +219,19 @@
     }
 
-    /* Getting the program header table offset and the number of segments. */
+    // Get program header table offset and number of segments
     phdr_offset     = elf_header->e_phoff;
     segments_nb     = elf_header->e_phnum;
 
-    /* Getting the program header table pointer. */
+    // Get program header table pointer
     program_header  = (Elf32_Phdr*)(KERN_BASE + phdr_offset);
 
-    /* Looking for loadable segments. */
+    // loop on segments
+    kcode_found = false;
+    kdata_found = false;
     for (seg_id = 0; seg_id < segments_nb; seg_id++) 
     {
-        // Found one:
-        if (program_header[seg_id].p_type == PT_LOAD)
+        if (program_header[seg_id].p_type == PT_LOAD)   // Found one loadable segment
         {
-            // Getting its attributes.
+            // Get segment attributes.
             seg_paddr    = program_header[seg_id].p_paddr;   
             seg_offset   = program_header[seg_id].p_offset;
@@ -239,53 +239,96 @@
             seg_memsz    = program_header[seg_id].p_memsz;
 
-            // Load it to its appropriate physical memory address.
+            // get segment base address in buffer
             seg_src_addr = (uint32_t)KERN_BASE + seg_offset;
-            boot_memcpy((void*)(KERN_IMG_TMP_BASE + seg_paddr), 
-                        (void*)seg_src_addr, 
-                               seg_filesz);
+
+            // Load segment to its final physical memory address
+            boot_memcpy( (void*)seg_paddr, 
+                         (void*)seg_src_addr, 
+                         seg_filesz );
+
+#if DEBUG_BOOT_ELF 
+boot_printf("\n[BOOT INFO] in %s for file %s : found loadable segment\n"
+            "   base = %x / size = %x\n",
+            __FUNCTION__ , KERNEL_PATHNAME , seg_paddr , seg_memsz );
+#endif
 
             // Fill remaining memory with zero if (filesz < memsz).
-            boot_memset((void*)(KERN_IMG_TMP_BASE + seg_paddr + seg_filesz),
-                                0,
-                                seg_memsz - seg_filesz);
-            
-            /* 
-             * Note: we suppose that the 'kernel.elf' file contains only 2 
-             * loadable segments ktext + kdata and that the main 
-             * difference between these two is the WRITE permission: ktext 
-             * contains read-only instructions and read_only data,
-             * while kdata contains writable data.
-             */
-
-            // Get ktext segment base and end addresses.
-            if ((program_header[seg_id].p_flags & PF_W) == 0)
-            {
-                ktext_base = seg_paddr;
-                ktext_end  = seg_paddr + seg_memsz;
-            }
-
-            // Get kdata segment base and end addresses.
-            else
-            {
-                kdata_base = seg_paddr;
-                kdata_end  = seg_paddr + seg_memsz;
+            if( seg_memsz < seg_filesz )
+            {
+                boot_memset( (void*)(seg_paddr + seg_filesz), 0, seg_memsz - seg_filesz);
+            }
+
+            // Note: we suppose that the 'kernel.elf' file contains only 2 
+            // loadable segments ktext & kdata and that the main 
+            // difference between these two is the WRITE permission: ktext 
+            // contains read-only instructions and read_only data,
+            // while kdata contains writable data.
+
+            if ((program_header[seg_id].p_flags & PF_W) == 0)  // kcode segment
+            {
+                if( kcode_found )
+                {
+                    boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
+                                "   two loadable kcode segments found\n",
+                                __FUNCTION__ , KERNEL_PATHNAME );
+                    boot_exit();
+                } 
+
+                kcode_found     = true;
+                seg_kcode_base = seg_paddr;
+                seg_kcode_size = seg_memsz;
+            }
+            else                                               // kdata segment
+            {
+                if( kdata_found )
+                {
+                    boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
+                                "   two loadable kdata segments found\n",
+                                __FUNCTION__ , KERNEL_PATHNAME );
+                    boot_exit();
+                } 
+
+                kdata_found     = true;
+                seg_kdata_base = seg_paddr;
+                seg_kdata_size = seg_memsz;
             }
         }
     }
 
-    // Get the entry point for kernel code.
+    // check kcode & kdata segments found
+    if( kcode_found == false )
+    {
+        boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
+                    "   kcode segment not found\n",
+                    __FUNCTION__ , KERNEL_PATHNAME );
+        boot_exit();
+    }
+    if( kdata_found == false )
+    {
+        boot_printf("\n[BOOT_ERROR] in %s for file %s :\n"
+                    "   kdata segment not found\n",
+                    __FUNCTION__ , KERNEL_PATHNAME );
+        boot_exit();
+    }
+
+    // set entry point 
     kernel_entry = (uint32_t)elf_header->e_entry;
 
+#if DEBUG_BOOT_ELF 
+boot_printf("\n[BOOT INFO] %s successfully completed for file %s at cycle %d\n",
+            __FUNCTION__ , KERNEL_PATHNAME , boot_get_proctime() );
+#endif
+
 } // boot_kernel_load()
 
-/****************************************************************************
- * This function initializes the local 'boot_info_t' structure.             *
- * @ boot_info  : pointer to local boot_info_t structure                    *
- * @ cxy        : cluster identifier                                        *
- ****************************************************************************/
+/*************************************************************************************
+ * This function initializes the  boot_info_t structure for a given cluster. 
+ * @ boot_info  : pointer to local boot_info_t structure  
+ * @ cxy        : cluster identifier                    
+ ************************************************************************************/
 static void boot_info_init( boot_info_t * boot_info,
                             cxy_t         cxy )
 {
-    archinfo_header_t  * header;        
+    archinfo_header_t  * header;
     archinfo_core_t    * core_base;     
     archinfo_cluster_t * cluster_base; 
@@ -294,4 +337,7 @@
 
     archinfo_cluster_t * cluster; 
+    archinfo_cluster_t * my_cluster = NULL;   // target cluster
+    archinfo_cluster_t * io_cluster = NULL;   // cluster containing ext. peripherals
+
     archinfo_core_t    * core;
     uint32_t             core_id; 
@@ -303,6 +349,15 @@
     boot_device_t      * boot_dev; 
 
-    // get pointer on ARCHINFO header 
-    header = (archinfo_header_t*)ARCHINFO_BASE;
+#if DEBUG_BOOT_INFO
+boot_printf("\n[BOOT INFO] %s : enter for cluster %x at cycle %d\n",
+            __FUNCTION__ , cxy , boot_get_proctime() );
+#endif
+
+    // get pointer on ARCHINFO header  and on the four arch_info arrays
+    header       = (archinfo_header_t*)ARCHINFO_BASE;
+    core_base    = archinfo_get_core_base   (header);
+    cluster_base = archinfo_get_cluster_base(header);
+    device_base  = archinfo_get_device_base (header);
+    irq_base     = archinfo_get_irq_base    (header);
 
     // Initialize global platform parameters
@@ -315,105 +370,87 @@
 
     // Initialize kernel segments
-    boot_info->kernel_code_start = ktext_base;
-    boot_info->kernel_code_end   = ktext_end;
-    boot_info->kernel_data_start = kdata_base;
-    boot_info->kernel_data_end   = kdata_end;
-
-    // Initialize specific cluster parameter
-    core_base    = archinfo_get_core_base   (header);
-    cluster_base = archinfo_get_cluster_base(header);
-    device_base  = archinfo_get_device_base (header);
-    irq_base     = archinfo_get_irq_base    (header);
-
-    // lopp on the clusters to find local cluster descriptor
+    boot_info->kernel_code_start = seg_kcode_base;
+    boot_info->kernel_code_end   = seg_kcode_base + seg_kcode_size;
+    boot_info->kernel_data_start = seg_kdata_base;
+    boot_info->kernel_data_end   = seg_kdata_base + seg_kdata_size;
+
+    // loop on arch_info clusters to get relevant pointers
     for (cluster =  cluster_base;
          cluster < &cluster_base[header->x_size * header->y_size];
          cluster++)
     {
-        if (cluster->cxy != cxy) continue;
-
-        boot_info->cxy          = cluster->cxy;
-        boot_info->cores_nr     = cluster->cores;
-        boot_info->devices_nr   = cluster->devices;
-
-#if DEBUG_BOOT_INFO
-boot_printf("\n[BOOT] build boot_info for cluster %x : %d cores / %d devices\n",
-            cluster->cxy , cluster->cores , cluster->devices );
-#endif
-        // Initialize array of core descriptors
-        for (core = &core_base[cluster->core_offset], core_id = 0;
-             core < &core_base[cluster->core_offset + cluster->cores];
-             core++, core_id++)
+        if( cluster->cxy  == cxy )            my_cluster = cluster;
+        if( cluster->cxy  == header->io_cxy ) io_cluster = cluster;
+    }
+
+    if( my_cluster == NULL ) 
+    {
+        boot_printf("\n[ERROR] in %s : cannot found cluster %x in arch_info\n",
+                    __FUNCTION__ , cxy );
+        boot_exit();
+    }
+
+    if( io_cluster == NULL ) 
+    {
+        boot_printf("\n[ERROR] in %s : cannot found io_cluster %x in arch_info\n",
+                    __FUNCTION__ , header->io_cxy );
+        boot_exit();
+    }
+
+    // loop on all arch-info peripherals in IO_cluster, 
+    // to initialize the boot_info array of external peripherals
+
+#if DEBUG_BOOT_INFO
+boot_printf("\n[BOOT INFO] %s : External peripherals\n", __FUNCTION__ );
+#endif
+
+    device_id = 0;
+    for (device = &device_base[io_cluster->device_offset];
+         device < &device_base[io_cluster->device_offset + io_cluster->devices];
+         device++ )
+    {
+        // initialise one entry for each external peripheral
+        if( (device->type != DEV_TYPE_RAM_SCL) &&
+            (device->type != DEV_TYPE_ICU_XCU) &&
+            (device->type != DEV_TYPE_MMC_TSR) &&
+            (device->type != DEV_TYPE_DMA_SCL) ) 
         {
-            boot_info->core[core_id].gid = (gid_t)core->gid;
-            boot_info->core[core_id].lid = (lid_t)core->lid; 
-            boot_info->core[core_id].cxy = (cxy_t)core->cxy;
-
-#if DEBUG_BOOT_INFO
-boot_printf("  - core %x : cxy = %x / lid = %d\n", 
-            core->gid , core->cxy , core->lid );
-#endif
-
+            boot_dev = &boot_info->ext_dev[device_id];
+
+            boot_dev->type     = device->type;
+            boot_dev->base     = device->base;
+            boot_dev->size     = device->size;
+            boot_dev->channels = device->channels;
+            boot_dev->param0   = device->arg0;    
+            boot_dev->param1   = device->arg1;    
+            boot_dev->param2   = device->arg2;    
+            boot_dev->param3   = device->arg3;    
+            boot_dev->irqs     = device->irqs;    
+
+            device_id++;
         }
 
-        // Initialize array of device descriptors
-        for (device = &device_base[cluster->device_offset], device_id = 0;
-             device < &device_base[cluster->device_offset + cluster->devices];
-             device++, device_id++)
-        {
-            boot_dev = &boot_info->dev[device_id];
-
-            boot_dev->type       =         device->type;
-            boot_dev->base       = (xptr_t)device->base;
-            boot_dev->size       =         device->size;
-            boot_dev->channels   =         device->channels;
-            boot_dev->param0     =         device->arg0;    
-            boot_dev->param1     =         device->arg1;    
-            boot_dev->param2     =         device->arg2;    
-            boot_dev->param3     =         device->arg3;    
-            boot_dev->irqs       =         device->irqs;    
-
-#if DEBUG_BOOT_INFO
-boot_printf("  - device %s : base = %l / size = %d / channels = %d / irqs = %d\n",
+#if DEBUG_BOOT_INFO
+boot_printf("  - %s : base = %l / size = %l / channels = %d / irqs = %d\n",
             device_type_str( device->type ) , device->base , device->size ,
             device->channels , device->irqs );   
 #endif
-
-            // Initialize information about physical memory in cluster
-            if (device->type == DEV_TYPE_RAM)
-            {
-                // Compute total number of physical memory pages in cluster
-                boot_info->pages_nr = device->size >> CONFIG_PPM_PAGE_SHIFT;
-
-                // Get the last address allocated for the kernel segments
-                uint32_t end = (ktext_end < kdata_end) ? kdata_end : ktext_end;
-
-                // Computing the number of pages allocated for the kernel.
-                if( (end & CONFIG_PPM_PAGE_MASK) == 0 )
-                {
-                    boot_info->pages_offset = end >> CONFIG_PPM_PAGE_SHIFT;
-                }
-                else
-                {
-                    boot_info->pages_offset = (end >> CONFIG_PPM_PAGE_SHIFT) + 1;
-                }
-            }
-            
-            // Initialize array of irq descriptors for XCU 
-            if (device->type == DEV_TYPE_XCU) 
-            {
-                for (irq_id = 0; irq_id < CONFIG_MAX_HWIS_PER_ICU; irq_id++)
-                {
-                    boot_dev->irq[irq_id].valid  = 0;
-                }
-
-                for (irq = &irq_base[device->irq_offset];
-                     irq < &irq_base[device->irq_offset + device->irqs];
-                     irq++)
-                {
-                    boot_dev->irq[irq->port].valid    = 1;
-                    boot_dev->irq[irq->port].dev_type = irq->dev_type;
-                    boot_dev->irq[irq->port].channel  = irq->channel;
-                    boot_dev->irq[irq->port].is_rx    = irq->is_rx;
+    
+        // Initialize array of irq descriptors for PIC
+        if (device->type == DEV_TYPE_PIC_TSR) 
+        {
+            for (irq_id = 0; irq_id < CONFIG_MAX_IRQS_PER_PIC; irq_id++)
+            {
+                boot_dev->irq[irq_id].valid  = 0;
+            }
+
+            for (irq = &irq_base[device->irq_offset];
+                 irq < &irq_base[device->irq_offset + device->irqs];
+                 irq++)
+            {
+                boot_dev->irq[irq->port].valid    = 1;
+                boot_dev->irq[irq->port].dev_type = irq->dev_type;
+                boot_dev->irq[irq->port].channel  = irq->channel;
+                boot_dev->irq[irq->port].is_rx    = irq->is_rx;
 
 #if DEBUG_BOOT_INFO
@@ -421,24 +458,126 @@
             irq->port , device_type_str( irq->dev_type ) , irq->channel , irq->is_rx );
 #endif
-
-                }
-            }
-
-            // Initialize array of irq descriptors for PIC
-            if (device->type == DEV_TYPE_PIC) 
-            {
-                for (irq_id = 0; irq_id < CONFIG_MAX_IRQS_PER_PIC; irq_id++)
-                {
-                    boot_dev->irq[irq_id].valid  = 0;
-                }
-
-                for (irq = &irq_base[device->irq_offset];
-                     irq < &irq_base[device->irq_offset + device->irqs];
-                     irq++)
-                {
-                    boot_dev->irq[irq->port].valid    = 1;
-                    boot_dev->irq[irq->port].dev_type = irq->dev_type;
-                    boot_dev->irq[irq->port].channel  = irq->channel;
-                    boot_dev->irq[irq->port].is_rx    = irq->is_rx;
+            }
+        }
+    }
+
+    // initialize number of external peripherals
+    boot_info->ext_dev_nr = device_id;
+
+    // Initialize cluster specific resources
+    boot_info->cxy  = my_cluster->cxy;
+
+#if DEBUG_BOOT_INFO
+boot_printf("\n[BOOT INFO] %s : cores in cluster %x\n", __FUNCTION__ );
+#endif
+
+    // Initialize array of core descriptors
+    core_id = 0;
+    for (core = &core_base[my_cluster->core_offset];
+         core < &core_base[my_cluster->core_offset + my_cluster->cores];
+         core++ )
+    {
+        boot_info->core[core_id].gid = (gid_t)core->gid;
+        boot_info->core[core_id].lid = (lid_t)core->lid; 
+        boot_info->core[core_id].cxy = (cxy_t)core->cxy;
+
+#if DEBUG_BOOT_INFO
+boot_printf("  - core_gid = %x : cxy = %x / lid = %d\n", 
+            core->gid , core->cxy , core->lid );
+#endif
+        core_id++;
+    }
+
+    // Initialize number of cores in my_cluster
+    boot_info->cores_nr = core_id;
+
+    // loop on all peripherals in my_cluster to initialise
+    // boot_info array of internal peripherals in my_cluster
+
+#if DEBUG_BOOT_INFO
+boot_printf("\n[BOOT INFO] %s : internal peripherals in cluster %x\n", __FUNCTION__ );
+#endif
+
+    device_id = 0;
+    for (device = &device_base[my_cluster->device_offset];
+         device < &device_base[my_cluster->device_offset + my_cluster->devices];
+         device++ )
+    {
+        // initialise one entry for each internal peripheral
+        if( (device->type == DEV_TYPE_RAM_SCL) ||
+            (device->type == DEV_TYPE_ICU_XCU) ||
+            (device->type == DEV_TYPE_MMC_TSR) ||
+            (device->type == DEV_TYPE_DMA_SCL) ) 
+        {
+            boot_dev = &boot_info->int_dev[device_id];
+
+            boot_dev->type     = device->type;
+            boot_dev->base     = device->base;
+            boot_dev->size     = device->size;
+            boot_dev->channels = device->channels;
+            boot_dev->param0   = device->arg0;    
+            boot_dev->param1   = device->arg1;    
+            boot_dev->param2   = device->arg2;    
+            boot_dev->param3   = device->arg3;    
+            boot_dev->irqs     = device->irqs; 
+   
+            device_id++;
+        }
+
+#if DEBUG_BOOT_INFO
+boot_printf("  - %s : base = %l / size = %l / channels = %d / irqs = %d\n",
+            device_type_str( device->type ) , device->base , device->size ,
+            device->channels , device->irqs );   
+#endif
+
+        // Initialize information about physical memory in cluster
+        if (device->type == DEV_TYPE_RAM_SCL)
+        {
+            // Compute total number of physical memory pages in cluster
+            boot_info->pages_nr = device->size >> CONFIG_PPM_PAGE_SHIFT;
+
+            // Get the last address allocated for the kernel segments
+            uint32_t end;
+            if( boot_info->kernel_code_end > boot_info->kernel_data_end )
+            {
+                end = boot_info->kernel_code_end;
+            }
+            else
+            {
+                end = boot_info->kernel_data_end;
+            }
+                
+            // Compute the number of pages allocated for the kernel.
+            if( (end & CONFIG_PPM_PAGE_MASK) == 0 )
+            {
+                boot_info->pages_offset = end >> CONFIG_PPM_PAGE_SHIFT;
+            }
+            else
+            {
+                boot_info->pages_offset = (end >> CONFIG_PPM_PAGE_SHIFT) + 1;
+            }
+
+#if DEBUG_BOOT_INFO
+boot_printf("    . physical memory : %x pages / first free page = %x\n",
+            boot_info->pages_nr , boot_info->pages_offset );
+#endif
+        }
+            
+        // Initialize array of irq descriptors for XCU 
+        if (device->type == DEV_TYPE_ICU_XCU) 
+        {
+            for (irq_id = 0; irq_id < CONFIG_MAX_HWIS_PER_ICU; irq_id++)
+            {
+                boot_dev->irq[irq_id].valid  = 0;
+            }
+
+            for (irq = &irq_base[device->irq_offset];
+                 irq < &irq_base[device->irq_offset + device->irqs];
+                 irq++)
+            {
+                boot_dev->irq[irq->port].valid    = 1;
+                boot_dev->irq[irq->port].dev_type = irq->dev_type;
+                boot_dev->irq[irq->port].channel  = irq->channel;
+                boot_dev->irq[irq->port].is_rx    = irq->is_rx;
 
 #if DEBUG_BOOT_INFO
@@ -447,22 +586,21 @@
 #endif
 
-                }
             }
         }
-
-#if DEBUG_BOOT_INFO
-boot_printf("  - ram : number of pages = %x / first free page = %x\n",
-            boot_info->pages_nr , boot_info->pages_offset );
-#endif
-
-    }
+    }
+
+    // initialize number of internal peripherals in my_cluster
+    boot_info->int_dev_nr = device_id;
+
+    // set boot_info signature
+    boot_info->signature = BOOT_INFO_SIGNATURE;
+
 } // boot_info_init()
 
-/****************************************************************************
- * This function is executed by all cores in order to check their           *
- * local boot_info_t structure.                                             *
- * @ boot_info  : pointer to local 'boot_info_t' structure to be checked.   *
- * @ lid        : core local identifier, index the core descriptor table.   *
- ****************************************************************************/
+/***********************************************************************************
+ * This function check the local boot_info_t structure for a given core.
+ * @ boot_info  : pointer to local 'boot_info_t' structure to be checked.
+ * @ lid        : core local identifier, index the core descriptor table.
+ **********************************************************************************/
 static void boot_check_core( boot_info_t * boot_info, 
                              lid_t         lid)
@@ -490,20 +628,16 @@
 } // boot_check_core()
 
-/****************************************************************************
- * This function is called by the bscpu to activate all other CP0s.         *
+/*********************************************************************************
+ * This function is called by CP0 in cluster(0,0) to activate all other CP0s.
  * It returns the number of CP0s actually activated.
- ****************************************************************************/
-static uint32_t boot_wake_cp0()
+ ********************************************************************************/
+static uint32_t boot_wake_all_cp0s()
 {
-    archinfo_header_t*  header;         /* Pointer on ARCHINFO header.      */
-    archinfo_cluster_t* cluster_base;   /* Pointer on ARCHINFO cluster 
-                                           base.                            */ 
-    archinfo_cluster_t* cluster;        /* Iterator for waking CP0 loop.    */
-    archinfo_device_t*  device_base;    /* Pointer on ARCHINFO peripheral 
-                                           device base.                     */
-    archinfo_device_t*  device;         /* Iterator for finding XICU device 
-                                           loop.                            */
-
-    uint32_t            cp0_nb = 0;     /* Number of CP0 woken up.          */
+    archinfo_header_t*  header;         // Pointer on ARCHINFO header
+    archinfo_cluster_t* cluster_base;   // Pointer on ARCHINFO clusters base
+    archinfo_cluster_t* cluster;        // Iterator for loop on clusters
+    archinfo_device_t*  device_base;    // Pointer on ARCHINFO devices base
+    archinfo_device_t*  device;         // Iterator for loop on devices
+    uint32_t            cp0_nb = 0;     // CP0s counter
 
     header       = (archinfo_header_t*)ARCHINFO_BASE;
@@ -528,12 +662,17 @@
             continue;
 
-        // Look for the XICU device associated to the CP0 of this cluster 
-        // then send an WTI to it in order to wake it up. 
+        // search XICU device associated to CP0, and send a WTI to activate it 
         for (device = &device_base[cluster->device_offset];
              device < &device_base[cluster->device_offset + cluster->devices];
              device++)
         {
-            if (device->type == DEV_TYPE_XCU)
-            {
+            if (device->type == DEV_TYPE_ICU_XCU)
+            {
+
+#if DEBUG_BOOT_WAKUP
+boot_printf("\n[BOOT] core[%x][0] activated at cycle %d\n",
+            cluster->cxy , boot_get_proctime );
+#endif
+
                 boot_remote_sw((xptr_t)device->base, (uint32_t)boot_entry);
                 cp0_nb++;
@@ -545,227 +684,182 @@
 } // boot_wake_cp0()
 
-/****************************************************************************
- * This function is called by all CP0 to activate all local CPi cores.      *
- * @ boot_info  : pointer to local 'boot_info_t' structure, used to find    *
- *                the XICU device associated with local CPi base addresses. *
- ****************************************************************************/
-static void boot_wake_local_cores(boot_info_t* boot_info)
+/*********************************************************************************
+ * This function is called by all CP0 to activate all local CPi cores. 
+ * @ boot_info  : pointer to local 'boot_info_t' structure, used to find
+ *                the XICU device associated with local CPi base addresses.
+ *********************************************************************************/
+static void boot_wake_local_cores(boot_info_t * boot_info)
 {
-    boot_device_t*  device;         // Iterator on devices
-    unsigned int    core_id;        // Iterator on cores
+    boot_device_t *  device;         // Iterator on devices
+    unsigned int     core_id;        // Iterator on cores
 
     // loop on devices to find XCU
-    for (device = &boot_info->dev[0];
-         device < &boot_info->dev[boot_info->devices_nr];
+    for (device = &boot_info->int_dev[0];
+         device < &boot_info->int_dev[boot_info->int_dev_nr];
          device++)
     {
-        if (device->type == DEV_TYPE_XCU)
+        if (device->type == DEV_TYPE_ICU_XCU)
         {
             // loop on cores
             for (core_id = 1; core_id < boot_info->cores_nr; core_id++)
+            {
+
+#if DEBUG_BOOT_WAKUP
+boot_printf("\n[BOOT] core[%x][%d] activated at cycle %d\n",
+             boot_info->cxy , core_id , boot_get_proctime() );
+#endif
                 boot_remote_sw((xptr_t) (device->base + (core_id << 2)),
                                (uint32_t)boot_entry); 
+            }
         }
     }
 } // boot_wake_local_cores()
 
-/****************************************************************************
- *                               API functions.                             *
- ****************************************************************************/
-
-/****************************************************************************
+
+/*********************************************************************************
  * This main function of the boot-loader is called by the  boot_entry()  
  * function, and executed by all cores. 
  * The arguments values are computed by the boot_entry code.
- * @ lid    : core local identifier in its cluster,
+ * @ lid    : core local identifier,
  * @ cxy    : cluster identifier,
- ****************************************************************************/
+ *********************************************************************************/
 void boot_loader( lid_t lid, 
                   cxy_t cxy )
 {
-    boot_info_t * boot_info;   // Pointer on local boot_info_t structure
-    uint32_t     local_count;  // Number of cores expected in local barrier                                  */
+    boot_info_t * boot_info;       // pointer on local boot_info_t structure
 
     if (lid == 0) 
     {
-        /**************************************
-         * PHASE ONE: only bscpu executes it. *
-         **************************************/
+        /****************************************************
+         * PHASE A : only CP0 in boot cluster executes it 
+         ***************************************************/
         if (cxy == BOOT_CORE_CXY)
         {
-            boot_printf("\n[BOOT] Starting on core[%d] in cluster %x at cycle %d\n",
-                        lid, cxy, boot_get_proctime());
+            boot_printf("\n[BOOT] core[%x][%d] enters at cycle %d\n",
+                        cxy , lid , boot_get_proctime() );
 
             // Initialize IOC driver 
             if      (USE_IOC_BDV) boot_bdv_init();
             else if (USE_IOC_HBA) boot_hba_init();
-            /*
-            else if (USE_IOC_SDC) boot_sdc_init();
-            else if (USE_IOC_SPI) boot_spi_init();
-            */
+            // else if (USE_IOC_SDC) boot_sdc_init();
+            // else if (USE_IOC_SPI) boot_spi_init();
             else if (!USE_IOC_RDK)
             {
-                boot_printf("\n[BOOT ERROR] boot_loader(): "
-                            "No IOC driver\n"
-                           );
+                boot_printf("\n[BOOT ERROR] in %s : no IOC driver\n");
                 boot_exit();
             }
 
-            // Initialize simplified version of FAT32. 
+            // Initialize FAT32. 
             boot_fat32_init();
+
+            // Load the 'kernel.elf' file into memory from IOC, and set   
+            // the global variables defining the kernel layout      
+            boot_kernel_load();
+
+            boot_printf("\n[BOOT] core[%x][%d] loaded kernel at cycle %d\n",
+                        cxy , lid , boot_get_proctime() );
 
             // Load the arch_info.bin file into memory.
             boot_archinfo_load();
 
-            // Load the 'kernel.elf' file into memory.
-            boot_kernel_load();
-
-            // Get local 'boot_info_t' structure base address.
+            // Get local boot_info_t structure base address.
             // It is the first structure in the .kdata segment. 
-            boot_info = (boot_info_t*)(KERN_IMG_TMP_BASE + kdata_base);
-
-            // Signature problem, abort program !!!
+            boot_info = (boot_info_t *)seg_kdata_base;
+
+            // Initialize local boot_info_t structure.
+            boot_info_init( boot_info , cxy );
+
+            // check boot_info signature
             if (boot_info->signature != BOOT_INFO_SIGNATURE)
             {
-                boot_printf("\n[BOOT] boot_loader(): "
-                            "boot_info signature should be %x\n",
-                            BOOT_INFO_SIGNATURE);
+                boot_printf("\n[BOOT ERROR] in %s reported by core[%x][%d]\n"
+                            "  illegal boot_info signature / should be %x\n",
+                            __FUNCTION__ , cxy , lid , BOOT_INFO_SIGNATURE );
                 boot_exit();
             }
 
-            // Initialize local 'boot_info_t' structure.
-            boot_printf("\n[BOOT] boot_loader(): "
-                        "Initializing the local boot_info_t structure "
-                        "at cycle %d\n",
-                        boot_get_proctime());
-
-            boot_info_init(boot_info, cxy);
+            boot_printf("\n[BOOT] core[%x][%d] loaded boot_info at cycle %d\n",
+                        cxy , lid , boot_get_proctime() );
 
             // Check core information.
             boot_check_core(boot_info, lid);
 
-            // Set the barrier.
-            boot_cluster_ready = 0;
-
-            // Activate other CP0s
-            boot_printf("\n[BOOT] boot_loader(): "
-                        "Waking other CP0 up at cycle %d\n",
-                        boot_get_proctime());
-
-            global_count = boot_wake_cp0();
-
-            // Wait until all CP0s ready to enter kernel.
-            boot_printf("\n[BOOT] boot_loader(): "
-                        "Waiting for other %d CP0 at cycle %d\n",
-                        global_count, boot_get_proctime());
-
-            boot_barrier(XPTR(BOOT_CORE_CXY, &global_barrier), 
-                         global_count);
-
-            // activate other local cores of the boot cluster.
-            local_barrier = 0;
-            boot_printf("\n[BOOT] boot_loader(): "
-                        "Waking other CPi up at cycle %d\n",
-                        boot_get_proctime());
-
-            boot_wake_local_cores(boot_info);
-
-            // Wait until all other local cores are ready 
-            boot_printf("\n[BOOT] boot_loader(): "
-                        "Waiting for other %d CPi at cycle %d\n",
-                        boot_info->cores_nr - 1, boot_get_proctime());
-
-            local_count = boot_info->cores_nr - 1;
-            while (local_barrier != local_count);
-
-            // Move the local kernel image at address 0x0 (erase preloader code).
-            boot_printf("\n[BOOT] boot_loader(): "
-                        "Moving the kernel image and erasing the preloader"
-                        "at cycle %d\n",
-                        boot_get_proctime());
-
-            // ktext segment.
-            boot_memcpy((void*)ktext_base,
-                        (void*)(KERN_IMG_TMP_BASE + ktext_base),
-                        ktext_end - ktext_base);
-
-            // kdata segment.
-            boot_memcpy((void*)kdata_base,
-                        (void*)(KERN_IMG_TMP_BASE + kdata_base),
-                        kdata_end - kdata_base);
-            
-            // activate other local cores.
-            boot_cluster_ready = 1;
-            boot_printf("\n[BOOT] boot_loader(): "
-                        "Everything is set, jumping to the kernel "
-                        "at cycle %d\n",
-                        boot_get_proctime());
+            // Activate other CP0s / get number of active CP0s
+            active_cp0s_nr = boot_wake_all_cp0s() + 1;
+
+            // Wait until all clusters (i.e all CP0s) ready to enter kernel.
+            boot_remote_barrier( XPTR( BOOT_CORE_CXY , &global_barrier ) ,
+                                 active_cp0s_nr );
+
+            // activate other local cores
+            boot_wake_local_cores( boot_info );
+
+            // Wait until all local cores in cluster ready
+            boot_remote_barrier( XPTR( cxy , &local_barrier ) , 
+                                 boot_info->cores_nr );
         }
-        /****************************************************
-         * PHASE TWO: all CP0s other than bscpu execute it. *
-         ****************************************************/
+        /******************************************************************
+         * PHASE B : all CP0s other than CP0 in boot cluster execute it
+         *****************************************************************/
         else
         {
-            /* 
-             * Note: at this point, we cannot access the global variables of
-             * this boot code since all the address extension registers for 
-             * DATA are pointing to their local cluster in order to have 
-             * access to the local stack and execute this C code. 
-             * However, all the address extension registers for INSTRUCTIONS 
-             * are still pointing to the boot cluster, thus we can access 
-             * and call functions defined in the boot code, for example 
-             * boot_remote_memcpy().
-             */
-
-            // Copy the boot-loader binary code 'boot.elf' into the local memory
-            boot_remote_memcpy(XPTR(cxy,           BOOT_BASE),
-                               XPTR(BOOT_CORE_CXY, BOOT_BASE),
-                               (unsigned int)BOOT_MAX_SIZE);
-
-            /*
-             * Note: from now on, it is safe to refer to the boot code global variables 
-             * such as the base address and size of the kernel segments.
-             */
-
-            // switch to the INSTRUCTION local memory space,  
-            // to avoid contention at the boot cluster.
+            // at this point, all INSTRUCTION address extension registers
+            // point on cluster(0,0), but the DATA extension registers point
+            // already on the local cluster to use the local stack. 
+            // To access the bootloader global variables we must first copy
+            // the boot code (data and instructions) in the local cluster.
+            boot_remote_memcpy( XPTR( cxy           , BOOT_BASE ),
+                                XPTR( BOOT_CORE_CXY , BOOT_BASE ),
+                                BOOT_MAX_SIZE );
+
+            // from now, it is safe to refer to the boot code global variables 
+            boot_printf("\n[BOOT] core[%x][%d] replicated boot code at cycle %d\n",
+                        cxy , lid , boot_get_proctime() );
+
+            // switch to the INSTRUCTION local memory space, to avoid contention.
             asm volatile("mtc2  %0, $25" :: "r"(cxy));
 
-            // Copy the 'arch_info.bin' file into the local memory.
+            // Copy the arch_info.bin file into the local memory.
             boot_remote_memcpy(XPTR(cxy,           ARCHINFO_BASE),
                                XPTR(BOOT_CORE_CXY, ARCHINFO_BASE),
-                               (unsigned int)ARCHINFO_MAX_SIZE);
-
-            // Copy the kernel image into local memory at address 0x0.
-            // ktext segment.
-            boot_remote_memcpy(XPTR(cxy, ktext_base),
-                               XPTR(BOOT_CORE_CXY, KERN_IMG_TMP_BASE + ktext_base),
-                               ktext_end - ktext_base);
-            // kdata segment.
-            boot_remote_memcpy(XPTR(cxy, kdata_base),
-                               XPTR(BOOT_CORE_CXY, KERN_IMG_TMP_BASE + kdata_base),
-                               kdata_end - kdata_base);
-
-            // Get local 'boot_info_t' structure base address.
-            // This is the first structure in the kdata segment.
-            boot_info = (boot_info_t*)kdata_base;
+                               ARCHINFO_MAX_SIZE );
+
+            boot_printf("\n[BOOT] core[%x][%d] replicated arch_info at cycle %d\n",
+                        cxy , lid , boot_get_proctime() );
+
+            // Copy the kcode segment into local memory 
+            boot_remote_memcpy( XPTR( cxy           , seg_kcode_base ),
+                                XPTR( BOOT_CORE_CXY , seg_kcode_base ),
+                                seg_kcode_size );
+
+            // Copy the kdata segment into local memory
+            boot_remote_memcpy( XPTR( cxy           , seg_kdata_base ),
+                                XPTR( BOOT_CORE_CXY , seg_kdata_base ),
+                                seg_kdata_size );
+
+            boot_printf("\n[BOOT] core[%x][%d] replicated kernel code at cycle %d\n",
+                        cxy , lid , boot_get_proctime() );
+
+            // Get local boot_info_t structure base address.
+            boot_info = (boot_info_t*)seg_kdata_base;
 
             // Initialize local boot_info_t structure.
-            boot_info_init(boot_info, cxy);
+            boot_info_init( boot_info , cxy );
 
             // Check core information.
-            boot_check_core(boot_info, lid);
-
-            // Activateall other local CPi cores in this cluster.
-            local_barrier = 0;
-            boot_wake_local_cores(boot_info);
-
-            // Waiting until all other local cores ready
-            local_count = boot_info->cores_nr - 1;
-            while (local_barrier != local_count);
-
-            // All cores in this cluster are ready to enter kernel.
-            boot_barrier(XPTR(BOOT_CORE_CXY, &global_barrier), 
-                         global_count);
+            boot_check_core( boot_info , lid );
+
+            // get number of active clusters from BOOT_CORE cluster
+            uint32_t count = boot_remote_lw( XPTR( BOOT_CORE_CXY , &active_cp0s_nr ) );
+
+            // Wait until all clusters (i.e all CP0s) ready to enter kernel
+            boot_remote_barrier( XPTR( BOOT_CORE_CXY , &global_barrier ) , count );
+
+            // activate other local cores
+            boot_wake_local_cores( boot_info );
+
+            // Wait until all local cores in cluster ready
+            boot_remote_barrier( XPTR( cxy , &local_barrier ) , 
+                                 boot_info->cores_nr );
         }
     }
@@ -773,36 +867,38 @@
     {
         /***************************************************************
-         * PHASE THREE: all non CP0 cores in all clusters execute it.  *
+         * PHASE C: all non CP0 cores in all clusters execute it
          **************************************************************/
 
-        if (cxy == BOOT_CORE_CXY)  // boot cluster only
-        {
-            // Report to the local CP0 that CPi is ready
-            boot_atomic_add((int32_t*)&local_barrier, 1);
-
-            // wait completion of kernel image move in  boot cluster
-            while (boot_cluster_ready != 1);
-
-            // Check core information
-            boot_info = (boot_info_t*)kdata_base;
-            boot_check_core(boot_info, lid);
-        }
-        else                      // other clusters
-        {
-            // Switch to the INSTRUCTIONS local memory space 
-            // to avoid contention at the boot cluster.
-            asm volatile("mtc2  %0, $25" :: "r"(cxy));
-
-            // Report to the local CP0 that CPi is ready
-            boot_atomic_add((int32_t*)&local_barrier, 1);
-
-            // Check core information
-            boot_info = (boot_info_t*)kdata_base;
-            boot_check_core(boot_info, lid);
-        }
-    }
-
-    // Jump to the kernel code. 
-    asm volatile("jr   %0" :: "r"(kernel_entry));
+        // Switch to the INSTRUCTIONS local memory space 
+        // to avoid contention at the boot cluster.
+        asm volatile("mtc2  %0, $25" :: "r"(cxy));
+
+        // Get local boot_info_t structure base address.
+        boot_info = (boot_info_t *)seg_kdata_base;
+
+        // Check core information
+        boot_check_core(boot_info, lid);
+
+        // Wait until all local cores in cluster ready
+        boot_remote_barrier( XPTR( cxy , &local_barrier ) , boot_info->cores_nr );
+    }
+
+    // Each core compute address of a temporary kernel stack 
+    // in the upper part of the local cluster memory...
+    uint32_t stack_ptr = ((boot_info->pages_nr - lid) << 12) - 16;
+
+    // All cores initialise stack pointer,
+    // reset the BEV bit in status register,
+    // register "boot_info" argument in a0,
+    // and jump to kernel_entry. 
+    asm volatile( "mfc0  $27,  $12           \n"
+                  "lui   $26,  0xFFBF        \n"
+                  "ori   $26,  $26,  0xFFFF  \n"
+                  "and   $27,  $27,  $26     \n"
+                  "mtc0  $27,  $12           \n" 
+                  "move  $4,   %0            \n"
+                  "move  $29,  %1            \n"
+                  "jr    %2                  \n"
+                  :: "r"(boot_info) , "r"(stack_ptr) , "r"(kernel_entry) );
 
 } // boot_loader()
Index: trunk/tools/bootloader_tsar/boot_bdv_driver.c
===================================================================
--- trunk/tools/bootloader_tsar/boot_bdv_driver.c	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_bdv_driver.c	(revision 6)
@@ -12,9 +12,17 @@
 
 #ifndef SEG_IOC_BASE
-# error "The SEG_IOC_BASE value should be defined in the 'boot_config.h' file"
+# error "The SEG_IOC_BASE value should be defined in the 'hard_config.h' file"
 #endif
 
-#ifndef IO_CXY
-# error "The IO_CXY value should be defined in the 'boot_config.h' file"
+#ifndef X_IO
+# error "The X_IO value should be defined in the 'hard_config.h' file"
+#endif
+
+#ifndef Y_IO
+# error "The Y_IO value should be defined in the 'hard_config.h' file"
+#endif
+
+#ifndef Y_WIDTH
+# error "The Y_WIDTH value should be defined in the 'hard_config.h' file"
 #endif
 
@@ -31,5 +39,5 @@
 static uint32_t boot_bdv_get_register( uint32_t reg )
 {
-    cxy_t      cxy = IO_CXY;
+    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
     uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
     
@@ -46,5 +54,5 @@
                                    uint32_t val )
 {
-    cxy_t      cxy = IO_CXY;
+    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
     uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
 
Index: trunk/tools/bootloader_tsar/boot_config.h
===================================================================
--- trunk/tools/bootloader_tsar/boot_config.h	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_config.h	(revision 6)
@@ -1,6 +1,5 @@
-/****************************************************************************
- * This file defines various hardware and configuration parameters for the  *
- * ALMOS-MKH boot-loader.                                                    *
- ****************************************************************************/
+/*********************************************************************************
+ * This file defines various configuration parameters for ALMOS-MKH boot-loader. 
+ ********************************************************************************/
 
 #ifndef _BOOT_CONFIG_H
@@ -8,40 +7,35 @@
 
 // Debug options
-#define DEBUG_BOOT_INFO     1
-#define DEBUG_BOOT_ELF      1
+#define DEBUG_BOOT_INFO     0
+#define DEBUG_BOOT_ELF      0
 #define DEBUG_BOOT_IOC      0
-#define DEBUG_BOOT_FAT32    1
-#define USE_FIXED_FORMAT    0
+#define DEBUG_BOOT_WAKUP    1
+#define DEBUG_BOOT_FAT32    0
 
-// io_cluster identifier
-#define IO_CXY              0
+// Core identifier format
+#define USE_FIXED_FORMAT    1
 
-// Peripheral base addresses (in io_cluster)
-#define SEG_IOC_BASE        0xb3000000
-#define SEG_TTY_BASE        0xb4000000
-#define SEG_MMC_BASE        0xb2000000
+// cache line
+#define CACHE_LINE_SIZE     64
+
+// Preloader temporary segment
+#define PRELOADER_BASE      0x0             /* Preloader base address.      */
+#define PRELOADER_MAX_SIZE  0x4000          /* Preloader max size.          */
 
 // boot code temporary segment
 #define BOOT_BASE           0x100000        /* 'boot.elf' base address.     */
-#define BOOT_MAX_SIZE       0x100000        /* 'boot.elf' max size.         */
+#define BOOT_MAX_SIZE       0x010000        /* 'boot.elf' max size.         */
 
 // arch_info temporary segment
-#define ARCHINFO_BASE       0x200000        /* 'arch_info.bin' base address */
-#define ARCHINFO_MAX_SIZE   0x200000        /* 'arch_info.bin' max size.    */
+#define ARCHINFO_BASE       0x200000        /* 'arch_info.bin' file base address */
+#define ARCHINFO_MAX_SIZE   0x010000        /* 'arch_info.bin' file max size.    */
 
 // kernel code temporary segment
-#define KERN_BASE           0x400000        /* 'kernel.elf' base address    */
-#define KERN_MAX_SIZE       0x100000        /* 'kernel.elf' max size.       */
-
-// Preloader temporary segment
-#define PRELOADER_BASE      0x0             /* Preloader base address.      */
-#define PRELOADER_MAX_SIZE  0x100000        /* Preloader max size.          */
+#define KERN_BASE           0x400000        /* 'kernel.elf' file base address    */
+#define KERN_MAX_SIZE       0x100000        /* 'kernel.elf' file max size.       */
 
 // Temporary stacks segments
 #define BOOT_STACK_BASE     0x504000        /* Boot stack base address.     */
-#define BOOT_STACK_SIZE     0x1000          /* Boot stack size (4Kb)        */
-
-// Pas clair du tout TODO   [AG]
-#define KERN_IMG_TMP_BASE   0X600000
+#define BOOT_STACK_SIZE     0x4000          /* Boot stack size (16Kb)       */
 
 #endif  // _BOOT_CONFIG_H
Index: trunk/tools/bootloader_tsar/boot_entry.S
===================================================================
--- trunk/tools/bootloader_tsar/boot_entry.S	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_entry.S	(revision 6)
@@ -1,2 +1,25 @@
+/*
+ * boot_entry.S - TSAR bootloader entry point.
+ * 
+ * Authors :   Alain Greiner / Vu Son  (2016)
+ *
+ * Copyright (c) UPMC Sorbonne Universites
+ *
+ * This file is part of ALMOS-MKH.
+ *
+ * ALMOS-MKH is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.0 of the License.
+ *
+ * ALMOS-MKH is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ALMOS-MKH; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
 /*************************************************************************************************
  * This file contains the entry point of the ALMOS-MK boot-loader for TSAR architecture.         *
@@ -61,26 +84,20 @@
     mfc0    k0,     CP0_PROCID          
     andi    k0,     k0,     0xFFF                       /* k0 <= gid                        */
-    andi    t1,     k0,     ((1 << PADDR_WIDTH) - 1)    /* t1 <= lid                        */
-    srl     t2,     k0,     PADDR_WIDTH                 /* t2 <= cxy                        */
+    andi    t1,     k0,     ((1 << P_WIDTH) - 1)        /* t1 <= lid                        */
+    srl     t2,     k0,     P_WIDTH                     /* t2 <= cxy                        */
     
-    /* 
-     * Initializing stack pointer from previously retrieved lid value.
-     */
+    /* Initialize stack pointer from previously retrieved lid value  */
     
     la      t0,     BOOT_STACK_BASE                     /* t0 <= BOOT_STACK_BASE            */
     li      k1,     BOOT_STACK_SIZE                     /* k1 <= BOOT_STACK_SIZE            */
     multu   k1,     t1
-    mflo    k0,                                         /* k0 <= BOOT_STACK_SIZE * lid      */
+    mflo    k0                                          /* k0 <= BOOT_STACK_SIZE * lid      */
     subu    sp,     t0,     k0                          /* P[cxy,lid] stack top initialized */ 
 
-    /* 
-     * Switching to local DSPACE by changing the value of the address extension registers.
-     */
+    /* Switch to local DSPACE by changing the value of the address extension registers  */
 
     mtc2    t2,     CP2_DATA_PADDR_EXT
 
-    /* 
-     * Jumping to boot_loader() function after passing 2 arguments in the registers.
-     */
+    /* Jump to boot_loader() function after passing 2 arguments in the registers  */
 
     or      a0,     zero,   t1                          /* a0 <= lid                        */     
@@ -96,7 +113,5 @@
  *************/
 
-    /* 
-     * Testing if this is bscpu.
-     */
+    /* Test if this is bscpu  */
 
     mfc0    k0,     CP0_PROCID          
@@ -108,7 +123,5 @@
     li      t4,     BOOT_CORE_CXY                       /* t4 <= bscpu cxy                  */
 
-    /* 
-     * Getting base address of the core descriptor table in 'arch_info.bin' file.
-     */
+    /* Get base address of the core descriptor table in 'arch_info.bin' file */
 
     la      t0,     ARCHINFO_BASE                       /* t0 <= ARCHINFO_BASE              */
@@ -116,7 +129,5 @@
     addu    t2,     t0,     t1                          /* t2 <= ARCHINFO_CORE_BASE         */
 
-    /* 
-     * Scanning the core descriptor table if this is not bscpu. TODO If not found?
-     */
+    /* scan the core descriptor table if this is not bscpu. TODO If not found?  */
 
     li      t3,     0x8                                 /* t3 <= ARCHINFO_CORE_SIZE         */
@@ -127,14 +138,10 @@
     addu    t2,     t2,     t3                          /* t2 <= @ next archinfo_core       */
 
-    /* 
-     * Getting (cxy, lid) values from the found core descriptor.
-     */
+    /* Get (cxy, lid) values from the found core descriptor  */
     
     lw      t3,     -8(t2)                              /* t3 <= lid                        */
     lw      t4,     -4(t2)                              /* t4 <= cxy                        */
 
-    /* 
-     * Initializing stack pointer from previously retrieved lid value.
-     */
+    /* Initialize stack pointer from previously retrieved lid value  */
 
 bscpu_exit:    
@@ -145,13 +152,9 @@
     subu    sp,     t0,     k0                          /* P[cxy,lid] stack top initialized */ 
 
-    /* 
-     * Switching to local DSPACE by changing the value of the address extension registers.
-     */
+    /* Switch to local DSPACE by changing the value of the address extension registers  */
 
     mtc2    t4,     CP2_DATA_PADDR_EXT
 
-    /* 
-     * Jumping to boot_loader() function after passing 2 arguments in the registers.
-     */
+    /* Jumping to boot_loader() function after passing 2 arguments in registers */
 
     or      a0,     zero,   t3                          /* a0 <= lid                        */     
Index: trunk/tools/bootloader_tsar/boot_fat32.c
===================================================================
--- trunk/tools/bootloader_tsar/boot_fat32.c	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_fat32.c	(revision 6)
@@ -148,5 +148,5 @@
 {
 #if DEBUG_BOOT_FAT32    
-    boot_printf("\n[BOOT] %s: Enters at cycle %d\n",
+    boot_printf("\n[BOOT INFO] %s enters at cycle %d\n",
                 __FUNCTION__ , boot_get_proctime() );
 #endif
@@ -163,5 +163,5 @@
 
 #if DEBUG_BOOT_FAT32    
-    boot_printf("\n[BOOT] %s: FSI Sector loaded at cycle %d\n",
+    boot_printf("\n[BOOT INFO] %s : FSI Sector loaded at cycle %d\n",
                 __FUNCTION__ , boot_get_proctime() );
 #endif
@@ -197,5 +197,5 @@
 
 #if DEBUG_BOOT_FAT32    
-    boot_printf("\n[BOOT] %s: free_clusters_nr = %x / free_cluster_hint = %x\n",
+    boot_printf("\n[BOOT INFO] %s : free_clusters_nr = %x / free_cluster_hint = %x\n",
                 __FUNCTION__ , boot_fat.free_clusters_nr , boot_fat.free_cluster_hint );
 #endif
@@ -430,5 +430,5 @@
 
 #if DEBUG_BOOT_FAT32    
-    boot_printf("\n[BOOT] %s: returns <%s> from <%s> at cycle %d\n",
+    boot_printf("\n[BOOT INFO] %s : returns <%s> from <%s> at cycle %d\n",
                 __FUNCTION__ , path_component , pathname , boot_get_proctime() );
 #endif
@@ -592,5 +592,5 @@
 
 #if DEBUG_BOOT_FAT32    
-    boot_printf("\n[BOOT] %s: Enters for <%s> file at cycle %d\n",
+    boot_printf("\n[BOOT INFO] %s enters for <%s> file at cycle %d\n",
                 __FUNCTION__ , pathname, boot_get_proctime());
 #endif
@@ -615,7 +615,4 @@
         while ( found == 0 )
         {
-
-boot_printf("\n!!! enter second while for <%s> path_comp\n", path_comp );
-
             cluster_lba = cluster_to_lba( parent_cluster );
             
@@ -646,7 +643,4 @@
                 if (ord == LAST_ENTRY)             // no more entry in this directory
                 {
-
-boot_printf("\n@@@ for <%s> component / offset = %d : last entry\n", path_comp , offset );
-
                     found = 2;
                 }
@@ -654,7 +648,4 @@
                 else if (ord == FREE_ENTRY)        // unused, check the next entry
                 {
-
-boot_printf("\n@@@ for <%s> component / offset = %d : free entry\n", path_comp , offset );
-
                     continue;
                 }
@@ -672,7 +663,4 @@
                     get_name_from_long(entry, buffer_lfn);
 
-boot_printf("\n@@@ for <%s> component / offset = %d : LFN entry = %s\n", 
-            path_comp , offset , buffer_lfn );
-
                     // Append this portion of the name to the full name buffer
                     boot_strcpy(name + 13 * (lfn_seq_order-1) , buffer_lfn);
@@ -685,7 +673,4 @@
                 {
                     if (lfn_seq_elem_nr == 0) get_name_from_short(entry, name);
-
-boot_printf("\n@@@ for <%s> component / offset = %d : SFN entry = %s\n", 
-            path_comp , offset , name );
 
                     // check if the full name is what we are looking for.
@@ -725,6 +710,4 @@
         } // end second while for one component in pathname
         
-boot_printf("\n### exit hwile fpr component <%s>\n", path_comp );
-
         // Check the result of this path component search.
         if (found == 2)
@@ -755,7 +738,7 @@
 
 #if DEBUG_BOOT_FAT32    
-    boot_printf("\n[BOOT] fat_file_search(): "
-                "<%s> file of size %x found at cluster %x at cycle %d\n",
-                pathname, *file_size, *first_cluster, boot_get_proctime());
+    boot_printf("\n[BOOT INFO] %s : <%s> file found at cycle %d\n"
+                "    fat_cluster = %x / size = %x\n",
+                __FUNCTION__ , pathname , boot_get_proctime() , *first_cluster , *file_size );
 #endif
 
@@ -771,7 +754,4 @@
 int boot_fat32_init()
 {
-
-boot_printf("@@@ BEFORE_VALUE = %x\n", FAT_MAGIC_VALUE);
-
     // FAT32 initialization should be done only once
     if (boot_fat.initialized == FAT_MAGIC_VALUE)
@@ -783,5 +763,5 @@
 
 #if DEBUG_BOOT_FAT32    
-boot_printf("\n[BOOT] %s: Enters at cycle %d\n",
+boot_printf("\n[BOOT INFO] %s: Enters at cycle %d\n",
             __FUNCTION__ , boot_get_proctime() );
 #endif
@@ -799,9 +779,6 @@
 
 #if DEBUG_BOOT_FAT32    
-boot_printf("\n[BOOT] %s: Boot Sector loaded at cycle %d\n",
+boot_printf("\n[BOOT INFO] %s: Boot Sector loaded at cycle %d\n",
             __FUNCTION__ , boot_get_proctime() );
-// unsigned char * data = boot_fat.block_buffer;
-// uint32_t   byte;
-// for( byte = 0 ; byte < 16 ; byte++ ) boot_printf("%d : %x\n", byte , data[byte] );
 #endif
 
@@ -865,8 +842,4 @@
     boot_fat.initialized    = FAT_MAGIC_VALUE;
 
-boot_printf("@@@ AFTER_VALUE = %x\n", FAT_MAGIC_VALUE);
-
-fat32_desc_display();
-    
     // Set information from FS Information Sector
     if (set_fsi()) return -1;
@@ -878,6 +851,6 @@
 #if DEBUG_BOOT_FAT32    
     fat32_desc_display();
-    boot_printf("\n[BOOT] boot_fat32_init(): FAT32 File System initialized at cycle %d\n",
-                boot_get_proctime());
+    boot_printf("\n[BOOT INFO] %s : FAT32 File System initialized at cycle %d\n",
+                __FUNCTION__ , boot_get_proctime() );
 #endif
 
@@ -907,5 +880,5 @@
 
 #if DEBUG_BOOT_FAT32    
-    boot_printf("\n[BOOT] %s: Enters for file <%s> at cycle %d\n",
+    boot_printf("\n[BOOT INFO] %s enters for file <%s> at cycle %d\n",
                 __FUNCTION__ , pathname, boot_get_proctime() );
 #endif
@@ -973,7 +946,7 @@
 
 #if DEBUG_BOOT_FAT32    
-    boot_printf("\n[BOOT] boot_fat32_load(): "
-                "File <%s> of size %x loaded at address %x at cycle %d\n",
-                pathname, size, buff_addr, boot_get_proctime());
+    boot_printf("\n[BOOT INFO] %s : file <%s> loaded at cycle %d\n"
+                "    address = %x , size = %x\n",
+                __FUNCTION__ , pathname , boot_get_proctime() , buff_addr , size );
 #endif
 
Index: trunk/tools/bootloader_tsar/boot_hba_driver.c
===================================================================
--- trunk/tools/bootloader_tsar/boot_hba_driver.c	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_hba_driver.c	(revision 6)
@@ -7,4 +7,5 @@
 
 #include <boot_config.h>
+#include <hard_config.h>
 #include <boot_hba_driver.h>
 #include <boot_mmc_driver.h>
@@ -15,6 +16,14 @@
 #endif
 
-#ifndef IO_CXY
-# error "The IO_CXY value should be defined in the 'boot_config.h' file"
+#ifndef Y_IO
+# error "The Y_IO value should be defined in the 'hard_config.h' file"
+#endif
+
+#ifndef X_IO
+# error "The X_IO value should be defined in the 'hard_config.h' file"
+#endif
+
+#ifndef Y_WIDTH
+# error "The Y_WIDTH value should be defined in the 'hard_config.h' file"
 #endif
 
@@ -47,5 +56,5 @@
 static uint32_t boot_hba_get_register(uint32_t reg)
 {
-    cxy_t      cxy = IO_CXY;
+    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
     uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
     
@@ -61,5 +70,5 @@
 void boot_hba_set_register(uint32_t reg, uint32_t val)
 {
-    cxy_t      cxy = IO_CXY;
+    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
     uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
 
Index: trunk/tools/bootloader_tsar/boot_tty_driver.c
===================================================================
--- trunk/tools/bootloader_tsar/boot_tty_driver.c	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_tty_driver.c	(revision 6)
@@ -1,8 +1,24 @@
-///////////////////////////////////////////////////////////////////////////////////
-// File     : boot_tty_driver.c
-// Date     : 18/01/2017
-// Author   : Alain Greiner / Vu Son
-// Copyright (c) UPMC-LIP6
-///////////////////////////////////////////////////////////////////////////////////
+/*
+ * boot_tty_driver.c - TSAR bootloader TTY driver implementation.
+ * 
+ * Authors :   Alain Greiner / Vu Son  (2016)
+ *
+ * Copyright (c) UPMC Sorbonne Universites
+ *
+ * This file is part of ALMOS-MKH.
+ *
+ * ALMOS-MKH is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.0 of the License.
+ *
+ * ALMOS-MKH is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ALMOS-MKH; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
 
 #include <boot_config.h>
@@ -11,26 +27,30 @@
 #include <boot_utils.h>
 
-#ifndef SEG_TTY_BASE
-# error "The SEG_TTY_BASE value should be defined in the 'boot_config.h' file"
+#ifndef SEG_TXT_BASE
+# error "The SEG_TXT_BASE value should be defined in the 'hard_config.h' file"
 #endif
 
-#ifndef IO_CXY
-# error "The IO_CXY value should be defined in the 'boot_config.h' file"
+#ifndef X_IO  
+# error "The X_IO value should be defined in the 'hard_config.h' file"
+#endif
+
+#ifndef Y_IO  
+# error "The Y_IO value should be defined in the 'hard_config.h' file"
+#endif
+
+#ifndef Y_WIDTH
+# error "The Y_WIDTH value should be defined in the 'hard_config.h' file"
 #endif
 
 
-/****************************************************************************
- *                            Internal functions.                           *
- ****************************************************************************/
-
-/****************************************************************************
- * This function returns the value of the a TTY register.                   *
- * @ reg    : TTY register to be read.                                      *
- * @ returns the value stored in 'reg'.                                     *
- ****************************************************************************/
+/////////////////////////////////////////////////////////////////////////////
+// This function returns the value contained in a TTY0 register. 
+// @ reg    : register to be read. 
+// @ returns the value stored in 'reg'.
+/////////////////////////////////////////////////////////////////////////////
 static uint32_t boot_tty_get_register( uint32_t reg )
 {
-    cxy_t      cxy = IO_CXY;
-    uint32_t * ptr = (uint32_t *)SEG_TTY_BASE + reg;
+    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
+    uint32_t * ptr = (uint32_t *)SEG_TXT_BASE + reg;
     
     return boot_remote_lw( XPTR( cxy , ptr ) ); 
@@ -38,14 +58,14 @@
 } // boot_tty_get_register()
 
-/****************************************************************************
- * This function sets a new value to a TTY register.                        *
- * @ reg    : TTY register to be configured.                                *
- * @ val    : new value to be written to 'reg'.                             *
- ****************************************************************************/
+/////////////////////////////////////////////////////////////////////////////
+// This function sets a new value to a TTY0 register.
+// @ reg    : register to be configured.
+// @ val    : new value to be written to 'reg'.
+/////////////////////////////////////////////////////////////////////////////
 static void boot_tty_set_register( uint32_t reg, 
                                    uint32_t val )
 {
-    cxy_t      cxy = IO_CXY;
-    uint32_t * ptr = (uint32_t *)SEG_TTY_BASE + reg;
+    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
+    uint32_t * ptr = (uint32_t *)SEG_TXT_BASE + reg;
 
     boot_remote_sw( XPTR( cxy , ptr ) , val ); 
@@ -53,41 +73,36 @@
 } // boot_tty_set_register()
 
-/****************************************************************************
- *                           Driver API functions.                          *
- ****************************************************************************/
-
+//////////////////////////////////
 int boot_tty_write( char    * buf,
                     uint32_t  nbytes )
 {
-    uint32_t nb_printed;    /* Iterator for printing loop.              */
-    uint32_t nb_test;       /* Iterator for retry loop.                 */
-    uint32_t error;         /* Used to detect if an error occurs.       */
+    uint32_t nb_printed;
+    uint32_t nb_test;
+    uint32_t error; 
 
-    /* Printing to the boot TTY terminal. */
+    // Print nbytes to TTY0 terminal
     for (nb_printed = 0; nb_printed < nbytes; nb_printed++)
     {
-        // Polling the TTY driver status.
-        if ((boot_tty_get_register(TTY_STATUS) & TTY_WRITE_BUSY))
+        // Poll the TTY0 status.
+        if ((boot_tty_get_register(TTY_STATUS_REG) & TTY_STATUS_TX_FULL))
         {
-            // TTY_WRITE_BUSY bit of TTY_STATUS register is set, keeps polling.
             error = 1;
             for (nb_test = 0; nb_test < 10000; nb_test++)
-                if ((boot_tty_get_register(TTY_STATUS) & TTY_WRITE_BUSY) == 0)
+            {
+                if ((boot_tty_get_register(TTY_STATUS_REG) & TTY_STATUS_TX_FULL) == 0)
                 {
                     error = 0;
                     break;
                 }
+            }
 
-            // Reporting an error if the TTY_WRITE_BUSY bit is still set after
-            // 10000 retries.
-            if (error)
-                return -1;
+            // Report error after 10000 retries.
+            if (error) return -1;
         }
 
-        // Writing a character to the boot TTY terminal. 
+        // Write one character to TTY0 terminal. 
         // Special treatment for a newline: Carriage Return before Line Feed.
-        if (buf[nb_printed] == '\n')
-            boot_tty_set_register(TTY_WRITE, (uint32_t)'\r');
-        boot_tty_set_register(TTY_WRITE, (uint32_t)buf[nb_printed]);
+        if (buf[nb_printed] == '\n') boot_tty_set_register(TTY_WRITE_REG , (uint32_t)'\r');
+        boot_tty_set_register(TTY_WRITE_REG , (uint32_t)buf[nb_printed]);
     }
 
Index: trunk/tools/bootloader_tsar/boot_tty_driver.h
===================================================================
--- trunk/tools/bootloader_tsar/boot_tty_driver.h	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_tty_driver.h	(revision 6)
@@ -1,10 +1,31 @@
+/*
+ * boot_tty_driver.h - TSAR bootloader TTY driver definition.
+ * 
+ * Authors :   Alain Greiner / Vu Son  (2016)
+ *
+ * Copyright (c) UPMC Sorbonne Universites
+ *
+ * This file is part of ALMOS-MKH.
+ *
+ * ALMOS-MKH is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.0 of the License.
+ *
+ * ALMOS-MKH is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ALMOS-MKH; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
 /****************************************************************************
- * This file defines a nano-driver for SocLib vci_multi_tty component, used *
- * by the ALMOS-MKH boot-loader.                                             *
- *                                                                          *
- * The SEG_TTY_BASE address must be defined in the 'hard_config.h' file.    *
- *                                                                          *
- * All accesses to the device registers are performed via 2 low-level       *
- * functions 'boot_tty_get_register()' and 'boot_tty_set_register()'.       *
+ * This file defines a nano-driver for SocLib vci_multi_tty component, 
+ * used by the ALMOS-MKH boot-loader.  
+ * The SEG_TTY_BASE address must be defined in the 'hard_config.h' file.
+ * All accesses to the device registers are performed via 2 low-level 
+ * functions 'boot_tty_get_register()' and 'boot_tty_set_register()'.
  ****************************************************************************/
 
@@ -20,8 +41,8 @@
 enum TTY_registers
 {
-    TTY_WRITE   = 0,    /* character to be displayed on screen              */
-    TTY_STATUS  = 1,    /* read and write buffer status                     */
-    TTY_READ    = 2,    /* character in the keyboard                        */
-    TTY_CONFIG  = 3,    /* unused                                           */
+    TTY_WRITE_REG   = 0,    /* character to be displayed on screen          */
+    TTY_STATUS_REG  = 1,    /* read and write buffer status                 */
+    TTY_READ_REG    = 2,    /* character in the keyboard                    */
+    TTY_CONFIG_REG  = 3,    /* unused                                       */
     
     TTY_SPAN    = 4,    /* segment size for one channel ( words )           */
@@ -34,21 +55,18 @@
 enum TTY_status
 {
-    TTY_READ_BUSY   = 1,    /* Set if TTY_READ register contains a data.    */
-    TTY_WRITE_BUSY  = 2,    /* Set if TTY_WRITE register contains a data.   */
+    TTY_STATUS_RX_FULL = 1, /* Set if TTY_READ register contains a data.    */
+    TTY_STATUS_TX_FULL = 2, /* Set if TTY_WRITE register contains a data.   */
 };
 
 /****************************************************************************
- *                           Driver API functions.                          *
- ****************************************************************************/
-
-/****************************************************************************
- * This function writes a character string from the 'buf' buffer to the     *
- * boot TTY terminal. It tests the TTY_STATUS register before writing each  *
- * character of the string to the TTY_WRITE register. If TTY_WRITE_BUSY     *
- * bit is set, it keeps testing the TTY_STATUS register. If after 10000     *
- * retries the bit is still set, the function reports an error and returns. *
- * @ buf    : buffer containing the string to be printed                    *
- * @ nbytes : number of characters to be printed                            *
- * @ returns 0 on success, -1 on error.                                     *
+ * This function writes a character string from the 'buf' buffer to the 
+ * boot TTY terminal. It tests the TTY_STATUS register before writing each
+ * character of the string to the TTY_WRITE register. If TTY_WRITE_BUSY 
+ * bit is set, it keeps testing the TTY_STATUS register. If after 10000 
+ * retries the bit is still set, the function reports an error and returns.
+ ****************************************************************************
+ * @ buf    : buffer containing the string to be printed.                
+ * @ nbytes : number of characters to be printed.                       
+ * @ returns 0 on success, -1 on error.     
  ****************************************************************************/
 int boot_tty_write( char    * buf,
Index: trunk/tools/bootloader_tsar/boot_utils.c
===================================================================
--- trunk/tools/bootloader_tsar/boot_utils.c	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_utils.c	(revision 6)
@@ -1,2 +1,25 @@
+/*
+ * boot_utils.c - TSAR bootloader utilities implementation.
+ * 
+ * Authors :   Alain Greiner / Vu Son  (2016)
+ *
+ * Copyright (c) UPMC Sorbonne Universites
+ *
+ * This file is part of ALMOS-MKH.
+ *
+ * ALMOS-MKH is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.0 of the License.
+ *
+ * ALMOS-MKH is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ALMOS-MKH; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
 #include <stdarg.h>
 
@@ -5,20 +28,27 @@
 #include <boot_utils.h>
 
+
+/****************************************************************************
+ *                        Global variables                                  *
+ ****************************************************************************/
+
+extern boot_remote_spinlock_t  tty0_lock;   // allocated in boot.c
+
 /****************************************************************************
  *                              Remote accesses.                            *
  ****************************************************************************/
 
+//////////////////////////////////
 uint32_t boot_remote_lw(xptr_t xp)
 {
-    uint32_t res;   /* Value to be read, stored at the remote address.      */
-    uint32_t ptr;   /* Classic pointer to the distant memory location.      */
-    uint32_t cxy;   /* Identifier of the cluster containing the distant
-                       memory location.                                     */
-
-    /* Extracting information from the extended pointer. */
+    uint32_t res;  
+    uint32_t ptr; 
+    uint32_t cxy;
+
+    // Extracting information from the extended pointer
     ptr = (uint32_t)GET_PTR(xp);
     cxy = (uint32_t)GET_CXY(xp);
 
-    /* Assembly instructions to get the work done. */
+    // Assembly instructions to get the work done. 
     asm volatile("mfc2  $15,    $24\n"  /* $15 <= CP2_DATA_PADDR_EXT        */
                  "mtc2  %2,     $24\n"  /* CP2_DATA_PADDR_EXT <= cxy        */
@@ -37,6 +67,5 @@
 } // boot_remote_lw()
 
-/****************************************************************************/
-
+/////////////////////////////////////////////
 void boot_remote_sw(xptr_t xp, uint32_t data)
 {
@@ -62,6 +91,5 @@
 } // boot_remote_sw()
 
-/****************************************************************************/
-
+//////////////////////////////////////////////////////
 int32_t boot_remote_atomic_add(xptr_t xp, int32_t val)
 {
@@ -98,7 +126,6 @@
 } // boot_remote_atomic_add()
 
-/****************************************************************************/
-
-void boot_remote_memcpy(xptr_t dest, xptr_t src, unsigned int size)
+///////////////////////////////////////////////////////////////
+void boot_remote_memcpy(xptr_t dest, xptr_t src, uint32_t size)
 {
     uint32_t words_nr;  /* Number of 32-bit words to be copied.             */
@@ -194,60 +221,58 @@
  ****************************************************************************/
 
-void boot_memcpy(void* dest, void* src, unsigned int size)
-{
-    /* Word-by-word copy if both addresses are word-aligned. */
-    if ((((unsigned int)dest & 0x3) == 0) && 
-        (((unsigned int)src & 0x3)  == 0))
-    {
-        // 'size' might not be a multiple of 4 bytes, we have to copy a few 
-        // bytes left (at most 3) byte-by-byte later.
+///////////////////////////////////////////////////////
+void boot_memcpy(void * dst, void * src, uint32_t size)
+{
+    uint32_t * wdst = dst;
+    uint32_t * wsrc = src;
+
+    // word-by-word copy if both addresses are word-aligned
+    if ( (((uint32_t)dst & 0x3) == 0) && (((uint32_t)src & 0x3)  == 0) )
+    {
         while (size > 3)
         {
-            *(unsigned int*)dest++ = *(unsigned int*)src++;
+            *wdst++ = *wsrc++;
             size -= 4;
         }
     }
 
-    /*
-     * Byte-by-byte copy if:
-     * - At least 1 of the 2 addresses is not word-aligned,
-     * - 'size' value is not a multiple of 4 bytes.
-     */
+    unsigned char * cdst = (unsigned char *)wdst;
+    unsigned char * csrc = (unsigned char *)wsrc;
+
+    // byte-by-byte copy if:
+    // - At least 1 of the 2 addresses is not word-aligned,
+    // - 'size' value is not a multiple of 4 bytes.
     while (size)
-        *(unsigned char*)dest++ = *(unsigned char*)src++;
-
+    {
+        *cdst++ = *csrc++;
+    }
 } // boot_memcpy()
 
-/****************************************************************************/
-
-void boot_memset(void* base, int val, unsigned int size)
-{
-    unsigned int wval;      /* Word-sized value to word-by-word filling.        */
-
-    /* Word-by-word filling if the base address is word-aligned. */
-    // Extracting the first 2 bytes of 'val'.
+////////////////////////////////////////////////////
+void boot_memset(void * dst, int val, uint32_t size)
+{
     val &= 0xFF;
-    // Making it word-sized. 
-    wval = (val << 24) | (val << 16) | (val << 8) | val;
-
-    if (((unsigned int)base & 0x3) == 0)
-    {
-        // 'size' might not be a multiple of 4 bytes, we have to fill a 
-        // few bytes left (at most 3) byte-by-byte later.
+
+    // build a word-sized value
+    uint32_t   wval = (val << 24) | (val << 16) | (val << 8) | val;
+    uint32_t * wdst = (uint32_t *)dst; 
+
+    // word per word if address aligned
+    if (((uint32_t)dst & 0x3) == 0)
+    {
         while (size > 3)
         {
-            *(unsigned int*)base++ = wval;
+            *wdst++ = wval;
             size -= 4;
         }
     }
     
-    /*
-     * Byte-by-byte filling if:
-     * - The base address is not word-aligned,
-     * - 'size' value is not a multiple of 4 bytes.
-     */
+    char * cdst = (char *)wdst;
+
+    // byte per byte
     while (size--)
-        *(unsigned char*)base++ = val;
-
+    {
+        *cdst++ = (char)val;
+    }
 } // boot_memset()
 
@@ -256,4 +281,5 @@
  ****************************************************************************/
 
+///////////////////////////////////////
 void boot_strcpy(char* dest, char* src)
 {
@@ -267,9 +293,8 @@
 } // boot_strcpy()
 
-/****************************************************************************/
-
-unsigned int boot_strlen(char* s)
-{
-    unsigned int res = 0;   /* Length of the string (in bytes).             */
+/////////////////////////////
+uint32_t boot_strlen(char* s)
+{
+    uint32_t res = 0;   /* Length of the string (in bytes).             */
 
     if (s != NULL)
@@ -283,6 +308,5 @@
 } // boot_strlen()
 
-/****************************************************************************/
-
+///////////////////////////////////
 int boot_strcmp(char* s1, char* s2)
 {
@@ -308,4 +332,5 @@
  ****************************************************************************/
 
+/////////////////////////
 void boot_puts(char* str)
 {
@@ -314,221 +339,163 @@
 } // boot_puts()
     
-/****************************************************************************/
-
-void boot_printf(char* format, ...)
-{
-    va_list      arg;           /* Used to iterate arguments list.          */
-    char         buf[16];       /* Buffer for argument conversion.          */      
-    char*        print_pt;      /* String pointer for argument printing.    */
-    int          arg_val;       /* Raw value of the argument.               */
-    unsigned int arg_len;       /* Length of a argument (in bytes).         */
-    unsigned int nb_printed;    /* Iterator for text printing loop.         */
-    unsigned int conv_index;    /* Index for argument conversion loop.      */
-
-    const char conv_tab[] = "0123456789ABCDEF";
-
-    /* Starting the arguments iterating process with a va_list. */
-    va_start(arg, format);
-
-print_text:
-    
-    while (*format)
-    {
-        /* Counting the number of ordinary characters. */
-        for (nb_printed = 0; 
-             (format[nb_printed] != '\0') && (format[nb_printed] != '%');
-             nb_printed++);
-
-        /* Copying them unchanged to the boot TTY terminal. */
-        if (nb_printed > 0)
+///////////////////////////////////////
+void boot_printf( char * format , ... )
+{
+    va_list args;
+    va_start( args , format );
+
+    // take the lock protecting TTY0
+    boot_remote_lock( XPTR( 0 , &tty0_lock ) );
+
+printf_text:
+
+    while ( *format ) 
+    {
+        uint32_t i;
+        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
+        if (i) 
         {
-            if (boot_tty_write(format, nb_printed))
-                goto error;
-            format += nb_printed;
+            boot_tty_write( format , i );
+            format += i;
         }
-
-        /* Skipping the '%' character. */
-        if (*format == '%')
+        if (*format == '%') 
         {
             format++;
-            goto print_argument;
+            goto printf_arguments;
         }
     }
 
-    /* Freeing the va_list. */
-    va_end(arg);
-
+    // release the lock
+    boot_remote_unlock( XPTR( 0 , &tty0_lock ) );
+
+    va_end( args );
     return;
 
-print_argument:
-
-    /* Analyzing the conversion specifier. */
-    switch (*format++)
-    {
-        // A character.
-        case ('c'):
+printf_arguments:
+
+    {
+        char      buf[20];
+        char    * pbuf = NULL;
+        uint32_t  len  = 0;
+        static const char HexaTab[] = "0123456789ABCDEF";
+        uint32_t i;
+
+        switch (*format++) 
         {
-            // Retrieving the argument.
-            arg_val  = va_arg(arg, int);
-
-            // Preparing for the printing. 
-            arg_len  = 1;
-            buf[0]   = arg_val;
-            print_pt = &buf[0];
-            break;
+            case ('c'):             /* char conversion */
+            {
+                int val = va_arg( args , int );
+                len = 1;
+                buf[0] = val;
+                pbuf = &buf[0];
+                break;
+            }
+            case ('d'):             /* 32 bits decimal signed  */
+            {
+                int val = va_arg( args , int );
+                if (val < 0) 
+                {
+                    val = -val;
+                    boot_tty_write( "-" , 1 );
+                }
+                for(i = 0; i < 10; i++) 
+                {
+                    buf[9 - i] = HexaTab[val % 10];
+                    if (!(val /= 10)) break;
+                }
+                len =  i + 1;
+                pbuf = &buf[9 - i];
+                break;
+            }
+            case ('u'):             /* 32 bits decimal unsigned  */
+            {
+                uint32_t val = va_arg( args , uint32_t );
+                for(i = 0; i < 10; i++) 
+                {
+                    buf[9 - i] = HexaTab[val % 10];
+                    if (!(val /= 10)) break;
+                }
+                len  = i + 1;
+                pbuf = &buf[9 - i];
+                break;
+            }
+            case ('x'):             /* 32 bits hexadecimal unsigned */
+            {
+                uint32_t val = va_arg( args , uint32_t );
+                boot_tty_write( "0x" , 2 );
+                for(i = 0; i < 8; i++) 
+                {
+                    buf[7 - i] = HexaTab[val & 0xF];
+                    if (!(val = (val>>4)))  break;
+                }
+                len =  i + 1;
+                pbuf = &buf[7 - i];
+                break;
+            }
+            case ('X'):             /* 32 bits hexadecimal unsigned  on 10 char */
+            {
+                uint32_t val = va_arg( args , uint32_t );
+                boot_tty_write( "0x" , 2 );
+                for(i = 0; i < 8; i++) 
+                {
+                    buf[7 - i] = HexaTab[val & 0xF];
+                    val = (val>>4);
+                }
+                len  = 8;
+                pbuf = buf;
+                break;
+            }
+            case ('l'):            /* 64 bits hexadecimal unsigned */
+            {
+                uint64_t val = va_arg( args , uint64_t );
+                boot_tty_write( "0x" , 2 );
+                for(i = 0; i < 16; i++) 
+                {
+                    buf[15 - i] = HexaTab[val & 0xF];
+                    if (!(val = (val>>4)))  break;
+                }
+                len  = i + 1;
+                pbuf = &buf[15 - i];
+                break;
+            }
+            case ('L'):           /* 64 bits hexadecimal unsigned on 18 char */ 
+            {
+                uint64_t val = va_arg( args , uint64_t );
+                boot_tty_write( "0x" , 2 );
+                for(i = 0; i < 16; i++) 
+                {
+                    buf[15 - i] = HexaTab[val & 0xF];
+                    val = (val>>4);
+                }
+                len  = 16;
+                pbuf = buf;
+                break;
+            }
+            case ('s'):             /* string */
+            {
+                char* str = va_arg( args , char* );
+                while (str[len]) 
+                {
+                    len++;
+                }
+                pbuf = str;
+                break;
+            }
+            default:
+            {
+                boot_tty_write( "\n[PANIC] in boot_printf() : illegal format\n", 43 );
+            }
         }
 
-        // A 32-bit signed decimal notation of an integer.
-        case ('d'):
-        {
-            // Retrieving the argument.
-            arg_val  = va_arg(arg, int);
-
-            // Printing the minus sign if needed.
-            if (arg_val < 0)
-            {
-                arg_val = -arg_val;
-                if (boot_tty_write("-", 1))
-                    goto error;
-            }
-
-            // Converting the argument raw value to a character string.
-            // Note that the maximum value for this type is 2.147.483.647 
-            // (2^31 - 1), a 10-digit number.
-            for (conv_index = 0; conv_index < 10; conv_index++)
-            {
-                // Writing to the buffer, starting from the least significant
-                // digit.
-                buf[9 - conv_index] = conv_tab[arg_val % 10];
-
-                // Getting to the next digit, stop when no more digit.
-                if ((arg_val /= 10) == 0)
-                    break;
-            }
-
-            // Preparing for the printing.
-            arg_len  = conv_index + 1;
-            print_pt = &buf[9 - conv_index];
-            break;
-        }
-
-        // A 32-bit unsigned decimal notation of an integer.
-        case ('u'):
-        {
-            // Retrieving the argument.
-            arg_val  = va_arg(arg, unsigned int);
-
-            // Converting the argument raw value to a character string.
-            // Note that the maximum value for this type is 4.294.967.295 
-            // (2^32 - 1), also a 10-digit number.
-            for (conv_index = 0; conv_index < 10; conv_index++)
-            {
-                // Writing to the buffer, starting from the least significant
-                // digit.
-                buf[9 - conv_index] = conv_tab[arg_val % 10];
-
-                // Getting to the next digit, stop when no more digit.
-                if ((arg_val /= 10) == 0)
-                    break;
-            }
-
-            // Preparing for the printing.
-            arg_len  = conv_index + 1;
-            print_pt = &buf[9 - conv_index];
-            break;
-        }
-
-        // A 32-bit unsigned hexadecimal notation of an integer.
-        case ('x'):
-        {
-            // Retrieving the argument.
-            arg_val  = va_arg(arg, unsigned int);
-
-            // Printing the hexadecimal prefix.
-            if (boot_tty_write("0x", 2))
-                goto error;
-
-            // Converting the argument raw value to a character string.
-            // Note that the maximum value for this type is 0xFFFFFFFF
-            // (2^32 - 1), a 8-digit hexadecimal number.
-            for (conv_index = 0; conv_index < 8; conv_index++)
-            {
-                // Writing to the buffer, starting from the least significant
-                // digit.
-                buf[7 - conv_index] = conv_tab[arg_val % 16];
-
-                // Getting to the next digit, stop when no more digit.
-                if ((arg_val >>= 4) == 0)
-                    break;
-            }
-
-            // Preparing for the printing.
-            arg_len  = conv_index + 1;
-            print_pt = &buf[7 - conv_index];
-            break;
-        }
-
-        // A 64-bit unsigned hexadecimal notation of an integer.
-        case ('l'):
-        {
-            // Retrieving the argument.
-            arg_val  = va_arg(arg, unsigned long long);
-
-            // Printing the hexadecimal prefix.
-            if (boot_tty_write("0x", 2))
-                goto error;
-
-            // Converting the argument raw value to a character string.
-            // Note that the maximum value for this type is 0xFFFFFFFFFFFFFFFF
-            // (2^64 - 1), a 16-digit hexadecimal number.
-            for (conv_index = 0; conv_index < 16; conv_index++)
-            {
-                // Writing to the buffer, starting from the least significant
-                // digit.
-                buf[15 - conv_index] = conv_tab[arg_val % 16];
-
-                // Getting to the next digit, stop when no more digit.
-                if ((arg_val >>= 4) == 0)
-                    break;
-            }
-
-            // Preparing for the printing.
-            arg_len  = conv_index + 1;
-            print_pt = &buf[15 - conv_index];
-            break;
-        }
-
-        // A NUL terminated string.
-        case ('s'):
-        {
-            // Retrieving the argument.
-            print_pt = va_arg(arg, char*);
-
-            // Preparing for the printing. 
-            arg_len  = boot_strlen(print_pt);
-            break;
-        }
-
-        default:
-            goto error;
-
-    }
-
-    /* Printing the converted argument. */
-    if (boot_tty_write(print_pt, arg_len))
-        goto error;
-
-    goto print_text;
-
-error:
-
-    /* Trying to print an error message then exit. */
-    boot_puts("\n[BOOT ERROR] boot_printf(): "
-              "Cannot print the whole message\n"
-             );
-
-    boot_exit();
-
-} // boot_printf()
+        if( pbuf != NULL ) boot_tty_write( pbuf, len );
+        
+        goto printf_text;
+    }
+}  // boot_printf()
+
+
+
+
+
 
 /****************************************************************************
@@ -536,20 +503,18 @@
  ****************************************************************************/
 
+////////////////
 void boot_exit()
 {
-    boot_printf("\n[BOOT PANIC] Suiciding at cycle %d...\n", 
-                boot_get_proctime()
-               );
-
-    while (1)
-        asm volatile ("nop");
+    boot_printf("\n[BOOT PANIC] core %x suicide at cycle %d...\n", 
+                boot_get_procid() , boot_get_proctime() );
+
+    while (1) asm volatile ("nop");
 
 } // boot_exit()
 
-/****************************************************************************/
-
-unsigned int boot_get_proctime()
-{
-    unsigned int res;       /* Value stored in the CP0_COUNT register.      */
+////////////////////////////
+uint32_t boot_get_proctime()
+{
+    uint32_t res;       /* Value stored in the CP0_COUNT register.      */
 
     asm volatile("mfc0 %0, $9" : "=r"(res));
@@ -559,9 +524,9 @@
 } // boot_get_proctime()
 
-/****************************************************************************/
-
-unsigned int boot_get_procid()
-{
-    unsigned int res;       /* Value stored in the CP0_PROCID register.     */
+
+//////////////////////////
+uint32_t boot_get_procid()
+{
+    uint32_t res;       /* Value stored in the CP0_PROCID register.     */
 
     asm volatile("mfc0 %0, $15, 1" : "=r"(res));
@@ -571,33 +536,26 @@
 } // boot_get_procid()
 
-/****************************************************************************/
-
-void boot_barrier(xptr_t xp_barrier, uint32_t count)
-{
-    boot_barrier_t* ptr;        /* Classic pointer to the toggling 
-                                   barrier.                                 */
-    uint32_t        cxy;        /* Identifier of the cluster containing
-                                   the toggling barrier.                    */
-    uint32_t        expected;   /* Expected barrier state after reset.      */
-    uint32_t        current;    /* Number of processors reached the 
-                                   barrier.                                 */
-
-    /* Extracting information from the extended pointer. */
-    ptr = (boot_barrier_t*)GET_PTR(xp_barrier);
-    cxy = (uint32_t)       GET_CXY(xp_barrier);
-
-    /* 
-     * Explicitly testing the barrier sense value because no initialization
-     * has been previously done.
-     */
-    if (boot_remote_lw(XPTR(cxy, &ptr->sense)) == 0)
-        expected = 1;
-    else
-        expected = 0;
+
+////////////////////////////////////////////////
+void boot_remote_barrier( xptr_t     xp_barrier, 
+                          uint32_t   count)
+{
+    boot_remote_barrier_t * ptr;
+    uint32_t                cxy;
+    uint32_t                expected;
+    uint32_t                current;
+
+    // Extract information from the extended pointer
+    ptr = (boot_remote_barrier_t*)GET_PTR(xp_barrier);
+    cxy = (uint32_t)              GET_CXY(xp_barrier);
+
+    // Explicitly test the barrier sense value because no initialization
+    if (boot_remote_lw(XPTR(cxy, &ptr->sense)) == 0) expected = 1;
+    else                                             expected = 0;
     
-    /* Incrementing the counter. */
+    // Atomically increment counter
     current = boot_remote_atomic_add(XPTR(cxy, &ptr->current), 1);
     
-    /* The processor arrived last resets the barrier and toggles its sense. */
+    // The processor arrived last resets the barrier and toggles its sense
     if (current == (count - 1))
     {
@@ -605,5 +563,5 @@
         boot_remote_sw(XPTR(cxy, &ptr->sense), expected);
     }
-    /* Other processors poll the sense. */
+    // Other processors poll the sense
     else
     {
@@ -613,2 +571,40 @@
 } // boot_barrier()
 
+////////////////////////////////////////
+void boot_remote_lock( xptr_t  lock_xp )
+
+{
+    // Extract information from the extended pointer
+    boot_remote_spinlock_t * ptr = (boot_remote_spinlock_t *)GET_PTR( lock_xp );
+    uint32_t                 cxy = GET_CXY( lock_xp );
+
+    // get next free ticket
+    uint32_t ticket = boot_remote_atomic_add( XPTR( cxy , &ptr->ticket ) , 1 );
+
+    // poll the current slot index
+    while ( boot_remote_lw( XPTR( cxy , &ptr->current ) ) != ticket )
+    {
+        asm volatile ("nop");
+    }
+
+}  // boot_remote_lock()
+
+/////////////////////////////////////////
+void boot_remote_unlock( xptr_t lock_xp )
+{
+    asm volatile ( "sync" );   // for consistency
+
+    // Extract information from the extended pointer
+    boot_remote_spinlock_t * ptr = (boot_remote_spinlock_t *)GET_PTR( lock_xp );
+    uint32_t                 cxy = GET_CXY( lock_xp );
+    xptr_t            current_xp = XPTR( cxy , &ptr->current );
+
+    // get current index value
+    uint32_t current = boot_remote_lw( current_xp );
+
+    // increment current index
+    boot_remote_sw( current_xp , current + 1 );
+
+}  // boot_remote_unlock()
+
+
Index: trunk/tools/bootloader_tsar/boot_utils.h
===================================================================
--- trunk/tools/bootloader_tsar/boot_utils.h	(revision 1)
+++ trunk/tools/bootloader_tsar/boot_utils.h	(revision 6)
@@ -1,2 +1,25 @@
+/*
+ * boot_utils.h - TSAR bootloader utilities definition.
+ * 
+ * Authors :   Alain Greiner / Vu Son  (2016)
+ *
+ * Copyright (c) UPMC Sorbonne Universites
+ *
+ * This file is part of ALMOS-MKH.
+ *
+ * ALMOS-MKH is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.0 of the License.
+ *
+ * ALMOS-MKH is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with ALMOS-MKH; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
 /****************************************************************************
  * This file defines various utility functions for the boot code.           *
@@ -26,43 +49,35 @@
 
 /****************************************************************************
- * This function reads an aligned 32-bit word from another memory address   *
- * space.                                                                   *
- * @ xp     : extended pointer to the distant memory location to be read    *
- *            from.                                                         *
- *                                                                          *
- * @ returns the value read.                                                *
+ * This function reads an aligned 32-bit word from a remote cluster.
+ * @ xp     : extended pointer to the distant memory location.
+ * @ returns the value read.      
  ****************************************************************************/
 uint32_t boot_remote_lw(xptr_t xp);
 
 /****************************************************************************
- * This function writes an aligned 32-bit word in another memory address    *
- * space.                                                                   *
- * @ xp     : extended pointer to the distant memory location to be written *
- *            to.                                                           *
- * @ data   : data value to be written to the distant memory location.      *
+ * This function writes an aligned 32-bit word to a remote cluster.
+ * @ xp     : extended pointer to the distant memory location.
+ * @ data   : data value to be written.
  ****************************************************************************/
 void boot_remote_sw(xptr_t xp, uint32_t data);
 
 /****************************************************************************
- * This function atomically adds an value 'val' to the current value stored *
- * at a distant memory location pointed to by the extended pointer 'xp'.    *
- * @ xp     : extended pointer to the distant memory location whose value   *
- *            is to be modified.                                            *
- * @ val    : signed value to be added.                                     *
- *                                                                          *
- * @ returns the value stored at the distant memory location BEFORE the     *
- *   atomic operation.                                                      *
+ * This function atomically adds a value 'val' to the current value stored 
+ * in a remote cluster.
+ * @ xp     : extended pointer to the distant memory location.
+ * @ val    : signed value to be added.
+ * @ returns the value stored BEFORE the atomic operation.
  ****************************************************************************/
 int32_t boot_remote_atomic_add(xptr_t xp, int32_t val);
 
 /****************************************************************************
- * This function copies 'size' bytes from the buffer pointed to by 'src'    *
- * to the buffer pointed to by 'dest'. These 2 addresses may be in any      *
- * different memory address spaces.                                         *
- * @ dest   : extended pointer to the destination buffer.                   *
- * @ src    : extended pointer to the source buffer.                        *
- * @ size   : size of memory block to be copied (in bytes).                 *   
- ****************************************************************************/
-void boot_remote_memcpy(xptr_t dest, xptr_t src, unsigned int size);
+ * This function copies 'size' bytes from the buffer pointed to by 'src'
+ * to the buffer pointed to by 'dest'. These 2 addresses may be in any 
+ * different memory address spaces.  
+ * @ dest   : extended pointer to the destination buffer. 
+ * @ src    : extended pointer to the source buffer. 
+ * @ size   : size of memory block to be copied (in bytes).   
+ ****************************************************************************/
+void boot_remote_memcpy(xptr_t dest, xptr_t src, uint32_t size);
 
 /****************************************************************************
@@ -71,11 +86,10 @@
 
 /****************************************************************************
- * This function atomically adds an value 'val' to the current variable     *
- * pointed to by 'ptr'. It only returns when the atomic operation is        *
- * successful.                                                              *
- * @ ptr    : pointer to the variable to be modified.                       *
- * @ val    : signed value to be added.                                     *
- *                                                                          *
- * @ returns the value of the variable BEFORE the atomic operation.         *
+ * This function atomically adds an value 'val' to the current variable  
+ * pointed to by 'ptr'. It only returns when the atomic operation is 
+ * successful.  
+ * @ ptr    : pointer to the variable to be modified.  
+ * @ val    : signed value to be added.
+ * @ returns the value of the variable BEFORE the atomic operation.  
  ****************************************************************************/
 int32_t boot_atomic_add(int32_t* ptr, int32_t val);
@@ -86,21 +100,21 @@
 
 /****************************************************************************
- * This function performs a local memory copy (destination and source       * 
- * addresses are in the same memory space) of 'size' bytes from 'src'       *
- * address to 'dest' address.                                               *
- * @ dest   : destination physical address,                                 *
- * @ src    : source physical address,                                      *
- * @ size   : size of memory block to be copied in bytes.                   *
- ****************************************************************************/
-void boot_memcpy(void* dest, void* src, unsigned int size);
-
-/****************************************************************************
- * This function fills the first 'size' bytes of the local memory area,     *
- * pointed to by 'base' with a constant value 'val'.                        *
- * @ base   : base address of the memory area to be initialized,            *
- * @ val    : value of the constant byte to initialize the area,            *
- * @ size   : size of memory block to be filled in bytes.                   *
- ****************************************************************************/
-void boot_memset(void* base, int val,   unsigned int size);
+ * This function performs a local memory copy (destination and source  
+ * addresses are in the same memory space) of 'size' bytes from 'src' 
+ * address to 'dest' address.                    
+ * @ dest   : destination physical address,  
+ * @ src    : source physical address,   
+ * @ size   : size of memory block to be copied in bytes.
+ ****************************************************************************/
+void boot_memcpy(void* dest, void* src, uint32_t size);
+
+/****************************************************************************
+ * This function fills the first 'size' bytes of the local memory area, 
+ * pointed to by 'base' with a constant value 'val'.                  
+ * @ base   : base address of the memory area to be initialized,   
+ * @ val    : value of the constant byte to initialize the area, 
+ * @ size   : size of memory block to be filled in bytes.   
+ ****************************************************************************/
+void boot_memset(void* base, int val,   uint32_t size);
 
 /****************************************************************************
@@ -109,9 +123,7 @@
 
 /****************************************************************************
- * This function converts the letter 'c' to lower case, if possible.        *
- * @ c  : letter to be converted.                                           *
- *                                                                          *
- * @ returns the converted letter, or 'c' if the conversion was not         *
- *   possible.                                                              *
+ * This function converts the letter 'c' to lower case, if possible. 
+ * @ c  : letter to be converted.                   
+ * @ returns the converted letter, or 'c' if conversion not possible.
  ****************************************************************************/
 static inline unsigned char boot_to_lower(unsigned char c)
@@ -122,9 +134,7 @@
 
 /****************************************************************************
- * This function converts the letter 'c' to upper case, if possible.        *
- * @ c  : letter to be converted.                                           *
- *                                                                          *
- * @ returns the converted letter, or 'c' if the conversion was not         *
- *   possible.                                                              *
+ * This function converts the letter 'c' to upper case, if possible.
+ * @ c  : letter to be converted. 
+ * @ returns the converted letter, or 'c' if conversion not possible.
  ****************************************************************************/
 static inline unsigned char boot_to_upper(unsigned char c)
@@ -135,26 +145,24 @@
 
 /****************************************************************************
- * This function copies the string pointed to by 'src' (the terminating     *
- * null byte '\0' NOT included) to the buffer pointed to by 'dest'.         *
- * @ src    : pointer to the string to be copied.                           *
- * @ dest   : pointer to the destination string.                            *
+ * This function copies the string pointed to by 'src' (the terminating 
+ * null byte '\0' NOT included) to the buffer pointed to by 'dest'. 
+ * @ src    : pointer to the string to be copied.  
+ * @ dest   : pointer to the destination string. 
  ****************************************************************************/
 void boot_strcpy(char* dest, char* src);
 
 /****************************************************************************
- * This function calculates the length of the string pointed to by 's',     *
- * excluding the terminating null byte '\0'.                                *
- * @ s  : pointer to the string whose length is to be computed.             *
- *                                                                          *
- * @ returns the number of bytes in the string.                             *
- ****************************************************************************/
-unsigned int boot_strlen(char* s);
-
-/****************************************************************************
- * This function compares the 2 strings pointed to by 's1' and 's2'.        *
- * @ s1 : pointer to the first string to be compared.                       *
- * @ s2 : pointer to the second string to be compared.                      *
- *                                                                          *
- * @ returns 0 if these 2 strings match, 1 otherwise.                       *
+ * This function calculates the length of the string pointed to by 's',
+ * excluding the terminating null byte '\0'.  
+ * @ s  : pointer to the string whose length is to be computed. 
+ * @ returns the number of bytes in the string. 
+ ****************************************************************************/
+uint32_t boot_strlen(char* s);
+
+/****************************************************************************
+ * This function compares the 2 strings pointed to by 's1' and 's2'.
+ * @ s1 : pointer to the first string to be compared.
+ * @ s2 : pointer to the second string to be compared.
+ * @ returns 0 if these 2 strings match, 1 otherwise. 
  ****************************************************************************/
 int boot_strcmp(char* s1, char* s2);
@@ -165,30 +173,30 @@
 
 /****************************************************************************
- * This function writes the NUL terminated string pointed to by 'str' to    *
- * the boot TTY terminal.                                                   *
- * @ str    : pointer to the string to be printed on the boot TTY terminal. *
+ * This function writes the NUL terminated string pointed to by 'str' 
+ * to the boot TTY terminal.                            
+ * @ str    : pointer to the string to be printed on the boot TTY terminal.
  ****************************************************************************/
 void boot_puts(char* str);
 
 /****************************************************************************
- * This function produces output, according to the 'format' format, to the  *
- * boot TTY terminal.                                                       *
- * @ format : the string defining the format of the output. It is composed  *
- *            of 0 or more directives:                                      *
- *            - ordinary characters (not %), which are copied unchanged to  *
- *              the boot TTY terminal.                                      *
- *            - conversion specifications (introduced by the character %,   *
- *              ended by a conversion specifier), each of which results in  *
- *              fetching 0 or more subsequent arguments. The arguments must *
- *              correspond properly (after type promotion) with the         *
- *              conversion specifier.                                       *
- *                                                                          *
- * Conversion specifiers:                                                   *
- *  - %d : 32-bit signed decimal notation of an integer,                    *
- *  - %u : 32-bit unsigned decimal notation of an integer,                  *
- *  - %x : 32-bit unsigned hexadecimal notation of an integer,              *
- *  - %l : 64-bit unsigned hexadecimal notation of an integer,              *
- *  - %c : character,                                                       *
- *  - %s : NUL terminated string.                                           *
+ * This function produces output, according to the 'format' format, to the 
+ * boot TTY terminal.
+ * @ format : the string defining the format of the output. It is composed 
+ *            of 0 or more directives:                                  
+ *            - ordinary characters (not %), which are copied unchanged to
+ *              the boot TTY terminal.                                  
+ *            - conversion specifications (introduced by the character %, 
+ *              ended by a conversion specifier), each of which results in 
+ *              fetching 0 or more subsequent arguments. The arguments must
+ *              correspond properly (after type promotion) with the  
+ *              conversion specifier.                            
+ *                                                            
+ * Conversion specifiers:                                  
+ *  - %d : 32-bit signed decimal notation of an integer,  
+ *  - %u : 32-bit unsigned decimal notation of an integer,
+ *  - %x : 32-bit unsigned hexadecimal notation of an integer, 
+ *  - %l : 64-bit unsigned hexadecimal notation of an integer,
+ *  - %c : character,                                     
+ *  - %s : NUL terminated string.  
  ****************************************************************************/
 void boot_printf(char* format, ...);
@@ -199,31 +207,29 @@
 
 /****************************************************************************
- * This function causes a termination during the boot procedure once the    *
- * boot code detects an error.                                              *
+ * This function causes a termination during the boot procedure once the 
+ * boot code detects an error. 
  ****************************************************************************/
 void boot_exit() __attribute__((noreturn));
 
 /****************************************************************************
- * This function returns the cycle count stored in the CP0_COUNT register   *
- * of the currently running processor.                                      *
- *                                                                          *
- * @ returns the processor cycle count.                                     *
- ****************************************************************************/
-unsigned int boot_get_proctime();
-
-/****************************************************************************
- * This function returns the global hardware identifier gid stored in the   *
- * CP0_PROCID register of the currently running processor.                  *
- *                                                                          *
- * @ returns the processor gid.                                             *
- ****************************************************************************/
-unsigned int boot_get_procid();
-
-/****************************************************************************
- * This structure defines a toggling barrier, that can be used to           *
- * synchronize a group of cores, whether or not they are in a same cluster, *
- * without any specific initialization.                                     *
- ****************************************************************************/
-typedef struct boot_barrier_s
+ * This function returns the cycle count stored in the CP0_COUNT register 
+ * of the currently running processor.  
+ * @ returns the processor cycle count. 
+ ****************************************************************************/
+uint32_t boot_get_proctime();
+
+/****************************************************************************
+ * This function returns the global hardware identifier gid stored in the 
+ * CP0_PROCID register of the currently running processor.
+ * @ returns the processor gid
+ ****************************************************************************/
+uint32_t boot_get_procid();
+
+/****************************************************************************
+ * This structure defines a toggling barrier, that can be used to  
+ * synchronize a group of cores, whether or not they are in a same cluster,
+ * without any specific initialization.   
+ ****************************************************************************/
+typedef struct boot_remote_barrier_s
 {
     uint32_t current;                      // Number of arrived cores
@@ -231,15 +237,40 @@
     uint32_t pad[(CACHE_LINE_SIZE>>2)-2];  // Padding
 }
-boot_barrier_t;
-
-/****************************************************************************
- * This function blocks all processors arriving at the barrier pointed to   *
- * by the extend pointer 'xp_barrier' and only returns when all 'count'     *
- * expected processors reach the barrier.                                   *
- * @ xp_barrier : extended pointer to a toggling barrier.                   *
- * @ count      : number of expected processors.                            *
- ****************************************************************************/
-void boot_barrier( xptr_t   xp_barrier, 
-                   uint32_t count );
+boot_remote_barrier_t;
+
+/****************************************************************************
+ * This function blocks all processors arriving at the barrier pointed to 
+ * by the extend pointer 'xp_barrier' and only returns when all 'count' 
+ * expected processors reach the barrier.  
+ * @ xp_barrier : extended pointer to a toggling barrier. 
+ * @ count      : number of expected processors.  
+ ****************************************************************************/
+void boot_remote_barrier( xptr_t   xp_barrier, 
+                          uint32_t count );
+
+/****************************************************************************
+ * This structure defines a remote queuing spinlock, that can be used to 
+ * synchronize a group of cores, whether or not they are in a same cluster,
+ * without any specific initialization.  
+ ****************************************************************************/
+typedef struct boot_remote_spinlock_s
+{
+    uint32_t     ticket;                       // next free ticket index        
+    uint32_t     current;                      // current owner index
+    uint32_t     pad[(CACHE_LINE_SIZE>>2)-2];  // Padding
+} 
+boot_remote_spinlock_t;
+
+/****************************************************************************
+ * This blocking function returns only when the lock is successfully taken.
+ * @ lock_xp    : extended pointer on lock.
+ ****************************************************************************/
+void boot_remote_lock( xptr_t  lock_xp );
+
+/****************************************************************************
+ * This function release the lock.
+ * @ lock_xp    : extended pointer on lock.
+ ****************************************************************************/
+void boot_remote_unlock( xptr_t  lock_xp );
 
 
