Index: /trunk/softs/tsar_boot/Makefile
===================================================================
--- /trunk/softs/tsar_boot/Makefile	(revision 585)
+++ /trunk/softs/tsar_boot/Makefile	(revision 586)
@@ -11,8 +11,8 @@
       DEFS+= -DSOCLIB_IOC
       DTS=platform_soclib.dts
-      $(info Making for $(PLATFORM_DIR), SocLib variant)
+      $(info Make for $(PLATFORM_DIR), SocLib variant)
     else
       DTS=platform_fpga.dts
-      $(info Making for $(PLATFORM_DIR), FPGA variant)
+      $(info Make for $(PLATFORM_DIR), FPGA variant)
     endif
   endif
@@ -51,8 +51,18 @@
 # =============================================================================
 
-CFLAGS     := -Wall -mno-gpopt -ffreestanding -fomit-frame-pointer -mips32 \
-		      -ggdb -mlong-calls -Werror
+CFLAGS     := -Wall                \
+              -mno-gpopt           \
+              -ffreestanding       \
+              -fomit-frame-pointer \
+              -mips32              \
+		      -ggdb                \
+              -mlong-calls         \
+              -Werror
 
-C_SRCS	   := boot_elf_loader.c boot_ioc.c boot_utils.c boot_tty.c exceptions.c
+C_SRCS	   := reset_elf_loader.c \
+              reset_ioc.c        \
+              reset_utils.c      \
+              reset_tty.c        \
+              reset_exception.c
 
 ifndef SOCLIB
@@ -66,5 +76,5 @@
 OBJS       := $(addprefix $(BUILD_DIR)/, $(OBJS))
 
-TARGET     := bin.soft
+TARGET     := preloader.elf
 
 USE_DT 	   ?= 1
@@ -72,14 +82,14 @@
 all: $(TARGET)
 
-$(BUILD_DIR)/version.o: $(BUILD_DIR) $(OBJS) version version.sh
-	$(ECHO) "[version.sh]"
-	./version.sh > $(BUILD_DIR)/version.c
-	$(ECHO) "[   CC    ]     $(BUILD_DIR)/version.c"
-	$(CC) $(DEFS) $(CFLAGS) $(INCLUDE) -c -o $@ $(BUILD_DIR)/version.c
-	$(DU) -D $@ > $@.txt
+# $(BUILD_DIR)/version.o: $(BUILD_DIR) $(OBJS) version version.sh
+#	$(ECHO) "[version.sh]"
+#	./version.sh > $(BUILD_DIR)/version.c
+#	$(ECHO) "[   CC    ]     $(BUILD_DIR)/version.c"
+#	$(CC) $(DEFS) $(CFLAGS) $(INCLUDE) -c -o $@ $(BUILD_DIR)/version.c
+#	$(DU) -D $@ > $@.txt
 
-$(TARGET): $(BUILD_DIR) $(BUILD_DIR)/version.o $(OBJS) $(PLATFORM_DIR)/ldscript $(BUILD_DIR)/platform.ld
+$(TARGET): $(BUILD_DIR) $(OBJS) $(PLATFORM_DIR)/ldscript $(BUILD_DIR)/platform.ld
 	$(ECHO) "[   LD    ]     $@"
-	$(LD) -o $@ -T $(PLATFORM_DIR)/ldscript $(OBJS) $(BUILD_DIR)/version.o
+	$(LD) -o $@ -T $(PLATFORM_DIR)/ldscript $(OBJS) 
 	$(DU) -D $@ > $@.txt
 
Index: /trunk/softs/tsar_boot/conf/platform_tsar_generic_iob/defs_platform.h
===================================================================
--- /trunk/softs/tsar_boot/conf/platform_tsar_generic_iob/defs_platform.h	(revision 585)
+++ /trunk/softs/tsar_boot/conf/platform_tsar_generic_iob/defs_platform.h	(revision 586)
@@ -1,16 +1,15 @@
-#define NB_PROCS        1
-#define NB_CLUSTERS     4
+#define NB_PROCS         1
+#define NB_CLUSTERS      4
 
-#define IRQ_PER_PROC    1
+#define IRQ_PER_PROC     1
 
-#define USE_IOB         1
-#define CACHE_COHERENCE 1
-#define CACHE_LINE_SIZE 64//bytes
+#define USE_IOB          1
+#define CACHE_COHERENCE  1
+#define CACHE_LINE_SIZE  64   //  bytes
 
-#define BOOT_DEBUG      1
-#define BOOT_DEBUG_IOC  0
+#define RESET_DEBUG      0
 
-#define ICU_BASE        0xB0000000
-#define MCC_BASE        0xB2000000
-#define IOC_BASE        0xB3000000
-#define TTY_BASE        0xB4000000
+#define ICU_PADDR_BASE   0xB0000000
+#define MCC_PADDR_BASE   0xB2000000
+#define IOC_PADDR_BASE   0xB3000000
+#define TTY_PADDR_BASE   0xB4000000
Index: /trunk/softs/tsar_boot/conf/platform_tsar_generic_iob/ldscript
===================================================================
--- /trunk/softs/tsar_boot/conf/platform_tsar_generic_iob/ldscript	(revision 585)
+++ /trunk/softs/tsar_boot/conf/platform_tsar_generic_iob/ldscript	(revision 586)
@@ -5,27 +5,31 @@
 **********************************************************/
 
-/* Definition of the base address for all segments */ 
+/* Definition of the base address for code segment */ 
 
-seg_stack_base    = 0x00040000;
-seg_boot_base     = 0xBFC00000;       /* le code de boot */
+seg_reset_code_base     = 0xBFC00000; 
+
+seg_reset_stack_base    = 0x00060000; 
+seg_reset_stack_size    = 0x00090000; 
 
 /* Grouping sections into segments */
 
-ENTRY(boot)
+ENTRY(reset)
+
 SECTIONS
 {
-    . = seg_boot_base;
-    .text : {
-        *(.boot)
+    . = seg_reset_code_base;
+    .text : 
+    {
         *(.reset)
-	*(.rodata)
-	*(.rodata.*)
-	. = ALIGN(0x4);
-	dtb_addr = .;
-	INCLUDE "build/platform.ld";
+        *(.rodata)
+        *(.rodata.*)
+        . = ALIGN(0x4);
+        dtb_addr = .;
+        INCLUDE "build/platform.ld";
     }
 
-    . = seg_stack_base;
-    .bss ALIGN(0x4) (NOLOAD) : {
+    . = seg_reset_stack_base;
+    .bss ALIGN(0x4) (NOLOAD) : 
+    {
         *(.data)
         *(.bss)
Index: unk/softs/tsar_boot/include/boot_ioc.h
===================================================================
--- /trunk/softs/tsar_boot/include/boot_ioc.h	(revision 585)
+++ 	(revision )
@@ -1,66 +1,0 @@
-#ifndef BOOT_IOC_H
-#define BOOT_IOC_H
-
-#ifndef SOCLIB_IOC
-#include <sdcard.h>
-#include <spi.h>
-#else
-#include <block_device.h>
-#include <mcc.h>
-#endif
-
-#include <defs.h>
-#include <boot_tty.h>
-#include <io.h>
-
-/**
- * boot_ioc_read()
- *
- * Transfer data from a file on the block device to a memory buffer.
- *
- * \param lba    : first block index on the disk
- * \param buffer : base address of the memory buffer
- * \param count  : number of blocks to be transfered
- *
- * \note This is a blocking function. The function returns once the transfer
- *       has finished
- */
-int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count);
-
-/**
- * boot_ioc_init()
- *
- * Initialize the SPI controller use to access a SD card
- */
-int boot_ioc_init();
-
-/**
- * boot_dbuf_invalidate()
- *
- * Invalidate all data cache lines corresponding to a memory buffer.
- */
-#if (CACHE_COHERENCE == 0)
-void boot_dbuf_invalidate(
-        const void * buffer,
-        unsigned int line_size,
-        unsigned int size);
-#endif
-
-/**
- * boot_ioc_write()
- *
- * Transfer data from a memory buffer to a file on the block_device.
- *
- * \param lba    : first block index on the disk
- * \param buffer : base address of the memory buffer
- * \param count  : number of blocks to be transfered
- *
- * \note The source buffer must be in user address space.
- */
-//int boot_ioc_write(unsigned int lba, void* buffer, unsigned int count);
-
-#endif
-
-/*
- * vim: tabstop=4 : shiftwidth=4 : expandtab
- */
Index: unk/softs/tsar_boot/include/boot_tty.h
===================================================================
--- /trunk/softs/tsar_boot/include/boot_tty.h	(revision 585)
+++ 	(revision )
@@ -1,14 +1,0 @@
-#ifndef BOOT_TTY_H
-#define BOOT_TTY_H
-
-#include <io.h>
-#include <tty.h>
-
-void boot_exit();
-int  boot_getc(char * c);
-void boot_putc(const char c);
-void boot_puts(const char *buffer);
-void boot_putx(unsigned int val);
-void boot_putd(unsigned int val);
-
-#endif
Index: unk/softs/tsar_boot/include/boot_utils.h
===================================================================
--- /trunk/softs/tsar_boot/include/boot_utils.h	(revision 585)
+++ 	(revision )
@@ -1,57 +1,0 @@
-/**
- * \file    : boot_utils.h
- * \date    : August 2012
- * \author  : Cesar Fuguet
- *
- * Definition of some miscellaneous functions used by the
- * pre-loader
- */
-
-#ifndef BOOT_UTILS_H
-#define BOOT_UTILS_H
-
-#include <elf-types.h>
-#include <boot_tty.h>
-
-/**
- * memcpy( _dst, _src, size )
- *
- * Transfer data between to memory buffers.
- *
- * \param _dst   : Destination buffer base address 
- * \param _src   : Source buffer base address
- * \param size   : Number of bytes to transfer 
- *
- */
-void * memcpy(void *_dst, const void *_src, unsigned int size);
-
-/**
- * memset( _dst, value, size )
- *
- * Initialize memory buffers with predefined value.
- *
- * \param _dst   : Destination buffer base address 
- * \param value  : Initialization value 
- * \param size   : Number of bytes to initialize
- *
- */
-void * memset(void *_dst, const int value, unsigned int size);
-
-/******************************************************************************
- * Misc functions for the ELF 
- *****************************************************************************/
-
-/**
- * boot_print_elf_phdr( elf_phdr_ptr )
- *
- * Print some fields of a ELF program header
- *
- * \param elf_phdr_ptr : Pointer to the ELF program header to print
- *
- */
-void boot_print_elf_phdr(Elf32_Phdr * elf_phdr_ptr);
-
-#endif
-
-// vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
-
Index: /trunk/softs/tsar_boot/include/defs.h
===================================================================
--- /trunk/softs/tsar_boot/include/defs.h	(revision 585)
+++ /trunk/softs/tsar_boot/include/defs.h	(revision 586)
@@ -1,8 +1,8 @@
 #include <defs_platform.h>
 
-#define BOOT_VERSION    0x00010001
+#define RESET_VERSION       0x00010002
 
-#define BOOT_STACK_SIZE 0x4000     /* 16 KB */
-#define BOOT_LOADER_LBA 2
-#define PHDR_ARRAY_SIZE	16
+#define RESET_STACKS_SIZE   0x11000  /* 64 bytes * 1024 + 4 Kbytes (for P0) = 68 Kbytes */
+#define BOOT_LOADER_LBA     2
+#define PHDR_ARRAY_SIZE	    16
 
Index: /trunk/softs/tsar_boot/include/reset_ioc.h
===================================================================
--- /trunk/softs/tsar_boot/include/reset_ioc.h	(revision 586)
+++ /trunk/softs/tsar_boot/include/reset_ioc.h	(revision 586)
@@ -0,0 +1,34 @@
+#ifndef RESET_IOC_H
+#define RESET_IOC_H
+
+#ifndef SOCLIB_IOC
+#include <sdcard.h>
+#include <spi.h>
+#else
+#include <block_device.h>
+#include <mcc.h>
+#endif
+
+#include <defs.h>
+#include <reset_tty.h>
+#include <io.h>
+
+extern int reset_ioc_init();
+
+extern int reset_ioc_read( unsigned int lba, 
+                           void*        buffer, 
+                           unsigned int count );
+
+extern int reset_ioc_completed();
+
+extern void reset_buf_invalidate ( const void * buffer,
+                                   unsigned int line_size,
+                                   unsigned int size );
+
+extern void reset_mcc_invalidate( const void * buffer,
+                                  unsigned int size );
+#endif
+
+/*
+ * vim: tabstop=4 : shiftwidth=4 : expandtab
+ */
Index: /trunk/softs/tsar_boot/include/reset_tty.h
===================================================================
--- /trunk/softs/tsar_boot/include/reset_tty.h	(revision 586)
+++ /trunk/softs/tsar_boot/include/reset_tty.h	(revision 586)
@@ -0,0 +1,13 @@
+#ifndef RESET_TTY_H
+#define RESET_TTY_H
+
+# include <tty.h> 
+
+void reset_exit();
+int  reset_getc(char * c);
+void reset_putc(const char c);
+void reset_puts(const char *buffer);
+void reset_putx(unsigned int val);
+void reset_putd(unsigned int val);
+
+#endif
Index: /trunk/softs/tsar_boot/include/reset_utils.h
===================================================================
--- /trunk/softs/tsar_boot/include/reset_utils.h	(revision 586)
+++ /trunk/softs/tsar_boot/include/reset_utils.h	(revision 586)
@@ -0,0 +1,24 @@
+/*
+ * \file    : reset_utils.h
+ * \date    : August 2012
+ * \author  : Cesar Fuguet
+ */
+
+#ifndef BOOT_UTILS_H
+#define BOOT_UTILS_H
+
+#include <elf-types.h>
+#include <reset_tty.h>
+
+extern unsigned int proctime();
+
+extern void* memcpy(void *_dst, const void *_src, unsigned int size);
+
+extern void* memset(void *_dst, const int value, unsigned int size);
+
+extern void reset_print_elf_phdr(Elf32_Phdr * elf_phdr_ptr);
+
+#endif
+
+// vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
+
Index: unk/softs/tsar_boot/src/boot_elf_loader.c
===================================================================
--- /trunk/softs/tsar_boot/src/boot_elf_loader.c	(revision 585)
+++ 	(revision )
@@ -1,360 +1,0 @@
-/**
- * \file    : boot_elf_loader.c
- * \date    : August 2012
- * \author  : Cesar Fuguet
- *
- * This file defines an elf file loader which reads an executable elf file
- * starting at a sector passed as argument of a disk and copy the different
- * ELF program segments in the appropriate memory address using as information
- * the virtual address read from the elf file.
- */
-
-#include <boot_ioc.h>
-#include <elf-types.h>
-#include <boot_tty.h>
-#include <boot_utils.h>
-#include <defs.h>
-
-#if (BOOT_DEBUG == 1)
-static char const * const init_state_str[] = {
-    "ELF_HEADER_STATE",
-    "ELF_PROGRAM_HEADER_STATE",
-    "ELF_OFFSET_STATE",
-    "ELF_SEGMENT_STATE",
-    "ELF_END_STATE"
-};
-#endif
-
-unsigned char boot_elf_loader_buffer[512] __attribute__((aligned(CACHE_LINE_SIZE)));
-
-void * boot_elf_loader(unsigned int lba)
-{
-    /*
-     * Temporary variables used by the boot loader
-     */
-    Elf32_Ehdr      elf_header;
-    Elf32_Phdr      elf_pht[PHDR_ARRAY_SIZE];
-
-    unsigned char * buffer_ptr;
-    Elf32_Ehdr    * elf_ehdr_ptr;
-    Elf32_Phdr    * elf_phdr_ptr;
-
-    unsigned int nb_available;
-    unsigned int nb_rest;
-    unsigned int nb_read;
-    unsigned int nb_block;
-    unsigned int offset;
-
-    unsigned char * pseg_ptr;
-    unsigned int pseg_start;
-    unsigned int pseg_end;
-    unsigned int pseg_remainder;
-    unsigned int pseg;
-
-    /*
-     * Loader state machine definition
-     */
-    typedef enum
-    {
-        ELF_HEADER_STATE,
-        ELF_PROGRAM_HEADER_STATE,
-        ELF_OFFSET_STATE,
-        ELF_SEGMENT_STATE,
-        ELF_END_STATE
-    } elf_loader_t;
-
-    elf_loader_t init_state;
-    init_state = ELF_HEADER_STATE;
-
-#if (BOOT_DEBUG == 1)
-    elf_loader_t init_state_debug;
-    init_state_debug = ELF_END_STATE;
-#endif
-
-    boot_puts("Starting boot_elf_loader function...\n\r");
-
-    nb_block     = lba;
-    nb_available = 0;
-    nb_rest      = sizeof(Elf32_Ehdr);
-    pseg         = 0;
-    offset       = 0;
-    elf_ehdr_ptr = (Elf32_Ehdr *) &elf_header;
-    elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0];
-
-    while(init_state != ELF_END_STATE)
-    {
-        if (nb_available == 0 )
-        {
-            buffer_ptr = &boot_elf_loader_buffer[0];
-
-            if (boot_ioc_read(nb_block , buffer_ptr, 1))
-            {
-                boot_puts (
-                    "ERROR: "
-                    "boot_ioc_read() failed"
-                    "\n"
-                );
-
-                boot_exit();
-            }
-
-            nb_block    += 1;
-            nb_available = 512;
-        }
-
-        nb_read  = (nb_rest <= nb_available) ? nb_rest : nb_available;
-        offset  +=  nb_read;
-
-#if (BOOT_DEBUG == 1)
-        if (init_state != init_state_debug)
-        {
-            boot_puts("\ninit_state = ");
-            boot_puts(init_state_str[init_state]);
-            boot_puts("\n");
-            init_state_debug = init_state;
-        }
-#endif
-
-        switch(init_state)
-        {
-            /*
-             * Reading ELF executable header
-             */
-            case ELF_HEADER_STATE:
-                memcpy(elf_ehdr_ptr, buffer_ptr, nb_read);
-
-                nb_rest -= nb_read;
-
-                if(nb_rest == 0)
-                {
-                    nb_rest = elf_ehdr_ptr->e_phnum * elf_ehdr_ptr->e_phentsize;
-
-                    /*
-                     * Verification of ELF Magic Number
-                     */
-                    if ( (elf_ehdr_ptr->e_ident[EI_MAG0] != ELFMAG0) ||
-                         (elf_ehdr_ptr->e_ident[EI_MAG1] != ELFMAG1) ||
-                         (elf_ehdr_ptr->e_ident[EI_MAG2] != ELFMAG2) ||
-                         (elf_ehdr_ptr->e_ident[EI_MAG3] != ELFMAG3) )
-                    {
-                        boot_puts(
-                            "ERROR: "
-                            "Input file does not use ELF format"
-                            "\n"
-                        );
-
-                        boot_exit();
-                    }
-
-                    /*
-                     * Verification of Program Headers table size. It must be
-                     * smaller than the work size allocated for the
-                     * elf_pht[PHDR_ARRAY_SIZE] array
-                     */
-                    if (elf_ehdr_ptr->e_phnum > PHDR_ARRAY_SIZE)
-                    {
-                        boot_puts(
-                            "ERROR: "
-                            "ELF PHDR table size is bigger than the allocated"
-                            "work space"
-                            "\n"
-                        );
-
-                        boot_exit();
-                    }
-
-                    init_state = ELF_PROGRAM_HEADER_STATE;
-                }
-
-                break;
-
-            /*
-             * Reading ELF program headers
-             */
-            case ELF_PROGRAM_HEADER_STATE:
-                memcpy(elf_phdr_ptr, buffer_ptr, nb_read);
-
-                elf_phdr_ptr = 
-                    (Elf32_Phdr *)((unsigned char *) elf_phdr_ptr + nb_read);
-
-                nb_rest -= nb_read;
-
-                if(nb_rest == 0)
-                {
-                    elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0];
-
-                    /*
-                     * Search the first not NULL segment in the ELF file
-                     */
-                    for (pseg = 0; pseg < elf_ehdr_ptr->e_phnum; pseg++)
-                    {
-                        if(elf_phdr_ptr[pseg].p_type == PT_LOAD)
-                        {
-#if (BOOT_DEBUG == 1)
-                            boot_puts("loadable segment found:\n");
-                            boot_print_elf_phdr(&elf_phdr_ptr[pseg]);
-#endif
-                            if (elf_phdr_ptr[pseg].p_offset < offset)
-                            {
-                                /* 
-                                 * Case where the segment to load includes the 
-                                 * elf and program headers 
-                                 */
-                                nb_rest = elf_phdr_ptr[pseg].p_filesz - offset;
-                                init_state = ELF_SEGMENT_STATE;
-                            }
-                            else
-                            {
-                                /* 
-                                 * Segment to load is further away in ELF file
-                                 */
-                                nb_rest = elf_phdr_ptr[pseg].p_offset - offset;
-                                init_state = ELF_OFFSET_STATE;
-                            }
-                            break;
-                        }
-                    }
-
-                    if (pseg == elf_ehdr_ptr->e_phnum)
-                    {
-                        boot_puts(
-                            "ERROR: "
-                            "No PT_LOAD found"
-                            "\n"
-                        );
-                        boot_exit();
-                    }
-
-                }
-
-                break;
-
-            /*
-             * Go to the offset of the first not null program segment in the
-             * ELF file
-             *
-             * TODO:
-             * No need to read from the disk the useless bytes. Try to compute
-             * the next usefull lba
-             */
-            case ELF_OFFSET_STATE:
-                nb_rest -= nb_read;
-
-                if (nb_rest == 0)
-                {
-                    nb_rest    = elf_phdr_ptr[pseg].p_filesz;
-                    init_state = ELF_SEGMENT_STATE;
-                }
-
-                break;
-
-            /*
-             * Reading ELF segments
-             *
-             * TODO:
-             * Do not pass by block buffer but write directly in target memory
-             * address
-             */
-            case ELF_SEGMENT_STATE:
-                /*
-                 * Verify that loadable segment does not conflict with
-                 * pre-loader memory space 
-                 */
-                pseg_start = elf_phdr_ptr[pseg].p_vaddr;
-
-                pseg_end   = elf_phdr_ptr[pseg].p_vaddr +
-                             elf_phdr_ptr[pseg].p_memsz;
-
-                if ((pseg_start >= 0xBFC00000 && pseg_start <= 0xBFC10000) ||
-                    (pseg_end   >= 0xBFC00000 && pseg_end   <= 0xBFC10000) ||
-                    (pseg_start <  0xBFC00000 && pseg_end   >  0xBFC10000))
-                {
-                    boot_puts(
-                        "ERROR: "
-                        "Program segment conflits with pre-loader memory space"
-                        "\n"
-                    );
-                    boot_exit();
-                }
-
-                /*
-                 * Copy the ELF segment data in memory using the
-                 * virtual address obtained from the ELF file
-                 */
-                pseg_ptr = (unsigned char *)
-                    elf_phdr_ptr[pseg].p_vaddr  +
-                    elf_phdr_ptr[pseg].p_filesz -
-                    nb_rest;
-
-                memcpy(pseg_ptr, buffer_ptr, nb_read);
-
-                nb_rest -= nb_read;
-
-                if (nb_rest == 0)
-                {
-                    /*
-                     * Fill remaining bytes with zeros (filesz < memsz)
-                     */
-                    pseg_remainder =
-                        elf_phdr_ptr[pseg].p_memsz  -
-                        elf_phdr_ptr[pseg].p_filesz ;
-
-                    pseg_ptr = (unsigned char *)
-                        elf_phdr_ptr[pseg].p_vaddr  +
-                        elf_phdr_ptr[pseg].p_filesz ;
-
-                    memset(pseg_ptr, 0, pseg_remainder);
-
-                    boot_puts("Copied segment at address ");
-                    boot_putx(elf_phdr_ptr[pseg].p_vaddr);
-                    boot_puts("\n");
-
-                    /*
-                     * Search the next first not NULL segment in the ELF file
-                     */
-                    for (pseg += 1; pseg < elf_ehdr_ptr->e_phnum; pseg++)
-                    {
-                        if(elf_phdr_ptr[pseg].p_type == PT_LOAD)
-                        {
-#if (BOOT_DEBUG == 1)
-                            boot_puts("loadable segment found:\n");
-                            boot_print_elf_phdr(&elf_phdr_ptr[pseg]);
-#endif
-                            nb_rest = elf_phdr_ptr[pseg].p_offset - offset;
-                            break;
-                        }
-                    }
-
-                    /*
-                     * Program loading finished
-                     */
-                    if(pseg == elf_ehdr_ptr->e_phnum)
-                    {
-                        init_state = ELF_END_STATE;
-                        break;
-                    }
-
-                    init_state = ELF_OFFSET_STATE;
-                }
-                break;
-
-            default:
-                break;
-        }
-
-        buffer_ptr   += nb_read;
-        nb_available -= nb_read;
-    }
-
-    boot_puts (
-        "Finishing boot_elf_loader function.\n"
-        "Entry point address: "
-    );
-
-    boot_putx(elf_ehdr_ptr->e_entry);
-    boot_puts("\n");
-
-    return ((void *) elf_ehdr_ptr->e_entry);
-}
-
-// vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
Index: unk/softs/tsar_boot/src/boot_ioc.c
===================================================================
--- /trunk/softs/tsar_boot/src/boot_ioc.c	(revision 585)
+++ 	(revision )
@@ -1,317 +1,0 @@
-#include <boot_ioc.h>
-
-#ifndef SOCLIB_IOC
-
-static struct sdcard_dev  _sdcard_device;
-static struct spi_dev   *const  _spi_device   = ( struct spi_dev * )IOC_BASE;
-
-#endif // end ifndef SOCLIB_IOC
-
-#define SDCARD_RESET_ITER_MAX 4
-
-inline void boot_sleep(int cycles)
-{
-    int i;
-    for (i = 0; i < cycles; i++);
-}
-
-#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
-inline unsigned int boot_proctime()
-{
-    unsigned int ret;
-    asm volatile ("mfc0 %0, $9":"=r" (ret));
-    return ret;
-}
-#endif
-
-#ifndef SOCLIB_IOC
-int boot_ioc_init()
-{
-    unsigned char sdcard_rsp;
-
-    boot_puts("Initializing block device\n\r");
-
-    /**
-     * Initializing the SPI controller
-     */
-    spi_dev_config (
-      _spi_device   ,
-      200000        , /**< SPI_clk: 200 Khz */
-      SYSCLK_FREQ   , /**< Sys_clk          */
-      8             , /**< Charlen: 8       */
-      SPI_TX_NEGEDGE,
-      SPI_RX_POSEDGE
-    );
-
-    /**
-     * Initializing the SD Card
-     */
-    unsigned int iter = 0;
-    while(1)
-    {
-        boot_puts("Trying to initialize SD card... ");
-
-        sdcard_rsp = sdcard_dev_open(&_sdcard_device, _spi_device, 0);
-        if (sdcard_rsp == 0)
-        {
-            boot_puts("OK\n");
-            break;
-        }
-
-        boot_puts("KO\n");
-        boot_sleep(1000);
-        if (++iter >= SDCARD_RESET_ITER_MAX)
-        {
-            boot_puts("\nERROR: During SD card reset to IDLE state\n"
-                      "/ card response = ");
-            boot_putx(sdcard_rsp);
-            boot_puts("\n");
-            boot_exit();
-        }
-    }
-
-    /**
-     * Set the block length of the SD Card
-     */
-    sdcard_rsp = sdcard_dev_set_blocklen(&_sdcard_device, 512);
-    if (sdcard_rsp)
-    {
-        boot_puts("ERROR: During SD card blocklen initialization\n");
-        boot_exit();
-    }
-
-    /**
-     * Incrementing SDCARD clock frequency for normal function
-     */
-    spi_dev_config (
-        _spi_device ,
-        10000000    , /**< SPI_clk 10 Mhz */
-        SYSCLK_FREQ , /**< Sys_clk        */
-        -1          , /**< Charlen: 8     */
-        -1          ,
-        -1
-    );
-
-    boot_puts("Finish block device initialization\n\r");
-
-    return 0;
-}
-#endif // end ifndef SOCLIB_IOC
-
-/**
- * _boot_ioc_completed()
- *
- * This blocking function checks completion of an I/O transfer and reports errors.
- *
- * \note It returns 0 if the transfer is successfully completed.
- *       It returns -1 if an error has been reported.
- */
-#ifdef SOCLIB_IOC
-static int _boot_ioc_completed()
-{
-    unsigned int status = 0;
-
-
-    unsigned int * ioc_address = ( unsigned int * )IOC_BASE;
-
-    while ( 1 )
-    {
-        status = ioread32(&ioc_address[BLOCK_DEVICE_STATUS]);
-
-        if (( status == BLOCK_DEVICE_READ_SUCCESS ) ||
-            ( status == BLOCK_DEVICE_READ_ERROR  ))
-        break;
-    }
-
-    return status;
-}
-#endif
-
-/**
- * boot_ioc_read()
- *
- * Transfer data from a file on the block device to a memory buffer.
- *
- * \param lba    : first block index on the disk
- * \param buffer : base address of the memory buffer
- * \param count  : number of blocks to be transfered
- *
- * \note This is a blocking function. The function returns once the transfer
- *       has finished
- */
-
-#ifdef SOCLIB_IOC
-///////////////////////////////////////////////////////////////////////////////
-// SOCLIB version of the boot_ioc_read function
-
-void boot_buf_invalidate (
-        const void * buffer,
-        unsigned int line_size,
-        unsigned int size);
-
-void boot_mcc_invalidate (
-        const void * buffer,
-        unsigned int size);
-
-int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
-{
-
-    unsigned int * ioc_address  = (unsigned int*)IOC_BASE;
-
-#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
-    unsigned int start_time;
-    unsigned int end_time;
-    boot_puts("[ DEBUG ] Reading blocks ");
-    boot_putd(lba);
-    boot_puts(" to ");
-    boot_putd(lba + count - 1);
-
-    start_time = boot_proctime();
-#endif
-
-    // block_device configuration
-    iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER],
-            ( unsigned int ) buffer );
-
-    iowrite32( &ioc_address[BLOCK_DEVICE_COUNT],
-            ( unsigned int ) count );
-
-    iowrite32( &ioc_address[BLOCK_DEVICE_LBA],
-            ( unsigned int ) lba );
-
-    iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE],
-            ( unsigned int ) 0 );
-
-    iowrite32( &ioc_address[BLOCK_DEVICE_OP],
-            ( unsigned int ) BLOCK_DEVICE_READ );
-
-    _boot_ioc_completed();
-
-#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
-    boot_buf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
-#endif
-
-#if (USE_IOB == 1)
-    boot_mcc_invalidate(buffer, count * 512);
-#endif
-
-#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
-    end_time = boot_proctime();
-
-    boot_puts(" / cycles for transfert: ");
-    boot_putd(end_time - start_time);
-    boot_puts("\n");
-#endif
-
-    return 0;
-}
-
-#else
-
-///////////////////////////////////////////////////////////////////////////////
-// FPGA version of the boot_ioc_read function
-
-int boot_ioc_read(unsigned int lba, void* buffer, unsigned int count)
-{
-    unsigned int sdcard_rsp;
-    unsigned int i;
-
-    sdcard_dev_lseek(&_sdcard_device, lba);
-
-#if (BOOT_DEBUG ==1 && BOOT_DEBUG_IOC == 1)
-    unsigned int start_time;
-    unsigned int end_time;
-    boot_puts("[ DEBUG ] Reading blocks ");
-    boot_putd(lba);
-    boot_puts(" to ");
-    boot_putd(lba + count - 1);
-
-    start_time = boot_proctime();
-#endif
-
-    for(i = 0; i < count; i++)
-    {
-        if (( sdcard_rsp = sdcard_dev_read (
-                        &_sdcard_device,
-                        (unsigned char *) buffer + (512 * i),
-                        512
-                        )
-            ))
-        {
-            boot_puts("ERROR during read on the SDCARD device. Code: ");
-            boot_putx(sdcard_rsp);
-            boot_puts("\n\r");
-
-            return 1;
-        }
-    }
-
-#if (BOOT_DEBUG == 1 && BOOT_DEBUG_IOC == 1)
-    end_time = boot_proctime();
-
-    boot_puts(" / cycles for transfert: ");
-    boot_putd(end_time - start_time);
-    boot_puts("\n");
-#endif
-
-    return 0;
-}
-#endif
-
-/**
- * _dcache_buf_invalidate()
- *
- * Invalidate all data cache lines corresponding to a memory
- * buffer (identified by an address and a size).
- */
-#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
-void boot_buf_invalidate (
-        const void * buffer,
-        unsigned int line_size,
-        unsigned int size)
-{
-    unsigned int i;
-
-    // iterate on cache lines
-    for (i = 0; i <= size; i += line_size) {
-        asm volatile(
-            " cache %0, %1"
-            :// no outputs
-            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
-            );
-    }
-}
-#endif
-
-/**
- * boot_mcc_inval()
- *
- * Invalidate all data cache lines corresponding to a memory
- * buffer (identified by an address and a size).
- */
-#if (USE_IOB == 1)
-void boot_mcc_invalidate (
-        const void * buffer,
-        unsigned int size)
-{
-    unsigned int * mcc_address = (unsigned int *)MCC_BASE;
-
-    // get the hard lock assuring exclusive access to MEMC
-    while (ioread32(&mcc_address[MCC_LOCK]));
-
-    // write invalidate paremeters on the memory cache
-    // this preloader use only the cluster 0 and then the HI bits are not used
-    
-    iowrite32(&mcc_address[MCC_ADDR_LO], (unsigned int) buffer);
-    iowrite32(&mcc_address[MCC_ADDR_HI], (unsigned int) 0);
-    iowrite32(&mcc_address[MCC_LENGTH] , (unsigned int) size);
-    iowrite32(&mcc_address[MCC_CMD]    , (unsigned int) MCC_CMD_INVAL);
-
-    // release the lock protecting MEMC
-    iowrite32(&mcc_address[MCC_LOCK], (unsigned int) 0);
-}
-#endif
-
-/*
- * vim: tabstop=4 : shiftwidth=4 : expandtab
- */
Index: unk/softs/tsar_boot/src/boot_tty.c
===================================================================
--- /trunk/softs/tsar_boot/src/boot_tty.c	(revision 585)
+++ 	(revision )
@@ -1,91 +1,0 @@
-#include <boot_tty.h>
-#include <defs.h>
-
-int boot_getc(char *c)
-{
-    unsigned int* tty_address = (unsigned int*) TTY_BASE;
-    if (ioread32(&tty_address[TTY_STATUS]) == 0)
-        return 0;
-
-    *c = ioread32(&tty_address[TTY_READ]);
-    return 1;
-}
-
-void boot_putc(const char c)
-{
-    unsigned int* tty_address = (unsigned int*) TTY_BASE;
-    iowrite32(&tty_address[TTY_WRITE], (unsigned int)c);
-
-    if (c == '\n')
-    {
-        iowrite32(&tty_address[TTY_WRITE], (unsigned int)'\r');
-    }
-}
-
-void boot_puts(const char *buffer) 
-{
-    unsigned int n;
-
-    for ( n=0; n<100; n++)
-    {
-        if (buffer[n] == 0) break;
-
-        boot_putc(buffer[n]);
-    }
-} 
-
-void boot_putx(unsigned int val)
-{
-    static const char HexaTab[] = "0123456789ABCDEF";
-    char              buf[11];
-    unsigned int      c;
-
-    buf[0]  = '0';
-    buf[1]  = 'x';
-    buf[10] = 0;
-
-    for ( c = 0 ; c < 8 ; c++ )
-    { 
-        buf[9-c] = HexaTab[val&0xF];
-        val = val >> 4;
-    }
-    boot_puts(buf);
-}
-
-void boot_putd(unsigned int val)
-{
-    static const char DecTab[] = "0123456789";
-    char              buf[11];
-    unsigned int      i;
-    unsigned int      first = 0;
-
-    buf[10] = 0;
-
-    for ( i = 0 ; i < 10 ; i++ )
-    {
-        if ((val != 0) || (i == 0))
-        {
-            buf[9-i] = DecTab[val % 10];
-            first    = 9-i;
-        }
-        else
-        {
-            break;
-        }
-        val /= 10;
-    }
-    boot_puts( &buf[first] );
-}
-
-void boot_exit()
-{
-    register int pid;
-    asm volatile( "mfc0 %0, $15, 1": "=r"(pid) );
-
-    boot_puts("\n!!! Exit Processor ");
-    boot_putx(pid);
-    boot_puts(" !!!\n");
-
-    while(1) asm volatile("nop");   // infinite loop...
-}
-
Index: unk/softs/tsar_boot/src/boot_utils.c
===================================================================
--- /trunk/softs/tsar_boot/src/boot_utils.c	(revision 585)
+++ 	(revision )
@@ -1,99 +1,0 @@
-/**
- * \file    : boot_utils.c
- * \date    : August 2012
- * \author  : Cesar Fuguet
- *
- * Definition of some miscellaneous functions used in by the
- * pre-loader
- */
-
-#include <boot_utils.h>
-
-/**
- * memcpy( _dst, _src, size )
- *
- * Transfer data between to memory buffers.
- *
- * \param _dst   : Destination buffer base address 
- * \param _src   : Source buffer base address
- * \param size   : Number of bytes to transfer 
- *
- */
-void * memcpy(void *_dst, const void *_src, unsigned int size)
-{
-    unsigned int *dst = _dst;
-    const unsigned int *src = _src;
-    if ( ! ((unsigned int)dst & 3) && ! ((unsigned int)src & 3) )
-        while (size > 3) {
-            *dst++ = *src++;
-            size -= 4;
-        }
-
-    unsigned char *cdst = (unsigned char*) dst;
-    unsigned char *csrc = (unsigned char*) src;
-
-    while (size--) {
-        *cdst++ = *csrc++;
-    }
-    return _dst;
-}
-
-/**
- * memset( _dst, value, size )
- *
- * Initialize memory buffers with predefined value.
- *
- * \param _dst   : Destination buffer base address 
- * \param value  : Initialization value 
- * \param size   : Number of bytes to initialize
- *
- */
-void * memset(void *_dst, const int value, unsigned int size)
-{
-    char * dst = (char *) _dst;
-
-    while(size--) *dst++ = (char) value;
-
-    return _dst;
-}
-
-/*
- * Misc functions for the ELF format
- */
-
-/**
- * boot_print_elf_phdr( elf_phdr_ptr )
- *
- * Print some fields of a ELF program header
- *
- * \param elf_phdr_ptr : Pointer to the ELF program header to print
- *
- */
-void boot_print_elf_phdr(Elf32_Phdr * elf_phdr_ptr)
-{
-    boot_puts("- type   : ");
-    boot_putx(elf_phdr_ptr->p_type);
-
-    boot_puts("\n- offset : ");
-    boot_putx(elf_phdr_ptr->p_offset);
-
-    boot_puts("\n- vaddr  : ");
-    boot_putx(elf_phdr_ptr->p_vaddr);
-
-    boot_puts("\n- paddr  : ");
-    boot_putx(elf_phdr_ptr->p_paddr);
-
-    boot_puts("\n- filesz : ");
-    boot_putx(elf_phdr_ptr->p_filesz);
-
-    boot_puts("\n- memsz  : ");
-    boot_putx(elf_phdr_ptr->p_memsz);
-
-    boot_puts("\n- flags  : ");
-    boot_putx(elf_phdr_ptr->p_flags);
-
-    boot_puts("\n- align  : ");
-    boot_putx(elf_phdr_ptr->p_align);
-}
-
-// vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
Index: unk/softs/tsar_boot/src/exceptions.c
===================================================================
--- /trunk/softs/tsar_boot/src/exceptions.c	(revision 585)
+++ 	(revision )
@@ -1,23 +1,0 @@
-/**
- * \file    : exceptions.c
- * \date    : December 2012
- * \author  : Manuel Bouyer
- *
- * This file defines a simple exceptions handler
- */
-
-#include <boot_tty.h>
-
-void handle_except(int status, int cause, int epc)
-{
-	boot_puts("tsar_boot (default) exception handler called: \r\n    status ");
-	boot_putx(status);
-	boot_puts("\r\n    cause  ");
-	boot_putx(cause);
-	boot_puts(" (exception ");
-	boot_putx((cause >> 2) & 0x1f);
-	boot_puts(")\r\n    epc    ");
-	boot_putx(epc);
-	boot_puts("\r\n");
-	while (1);
-}
Index: /trunk/softs/tsar_boot/src/reset.S
===================================================================
--- /trunk/softs/tsar_boot/src/reset.S	(revision 585)
+++ /trunk/softs/tsar_boot/src/reset.S	(revision 586)
@@ -1,23 +1,33 @@
-/**
+/*
  * \file  : reset.S
  * \date  : 01/12/2012
  * \author: Cesar FUGUET & Manuel BOUYER & Alain Greiner
  *
- * This is a boot code for a generic multi-clusters / multi-processors
- * TSAR architecture (up to 256 clusters / up to 4  processors per cluster). 
- * There is one XICU, one TTY, one DMA and one stack segment per cluster.
- * segment base adresses = base + cluster_segment_increment*cluster_id
- *
- * - Each processor initializes the Status Register (SR) to disable interrupts.
- * - Each processor initializes the Count Register.
- * - Each processor initialises its private XICU Write Triggered Interruption
- *   mask register.
- * - Only processor 0 initializes the stack pointer ($29).
- * - Only processor 0 (boot processor) executes the boot_load_elf function to
- *   load in memory the boot loader stored in the block BOOT_LOADER_LBA of 
- *   the disk.
- * - All non-boot processors wait in a low power consumption mode that the
- *   processor 0 wakes them using the IPI (Inter Processor Interruption)
- *   functionality of the XICU device.
+ * This is a generic reset code for a generic multi-clusters / multi-processors
+ * TSAR architecture (up to 256 clusters / up to 4  processors per cluster).
+ *
+ * There is one XICU, one TTY, one DMA, and one memory bank per cluster.
+ *
+ * This preloader uses a stack segment allocated in cluster 0, defined
+ * by the seg_reset_stack_base and seg_reset_stack_size parameters in ldscript.
+ * - Processor 0 uses a larger stack:         64 Kbytes.
+ * - Other processors use a smaller stack:    512 bytes.
+ *     => the seg_stack_size cannot be smaller than 0x90000 bytes (576 K).
+ * Those stacks can be used by both the preloader and the boot-loader code.
+ * 
+ * The replicated XICU is used to awake the sleeping processors:
+ *      xicu_paddr_base = ICU_PADDR_BASE + (cluster_id << 32)
+ *
+ * It is intended to be used with various operating systems or nano kernels,
+ * including NetBSD, ALMOS, and GIET_VM.
+ *
+ * - Each processor initializes its Status Register (SR) to disable interrupts.
+ * - Each processor initializes its Count Register.
+ * - Each processor initialises its private XICU WTI mask register.
+ * - Each processor initializes its Stack Pointer.
+ * - Only processor 0 executes the reset_load_elf function to load into memory 
+ *   the system specific boot-loader stored on disk at BOOT_LOADER_LBA 
+ * - All other processors wait in a low power consumption mode that the
+ *   processor 0 wakes them using an IPI (Inter Processor Interruption)
  */
 
@@ -25,50 +35,54 @@
     #include <mips32_registers.h>
 
-    .section .boot,"ax",@progbits
-
-    .extern seg_stack_base
+    /* These define should be consistent with values defined in ma;xml file  */
+
+    .extern seg_reset_stack_base  
+    .extern seg_reset_stack_size    
+
+    .section .reset,"ax",@progbits
 
     .extern dtb_addr
-    .extern boot_putc
-    .extern boot_getc
-    .extern boot_ioc_read
-    .extern boot_elf_loader
+    .extern reset_putc
+    .extern reset_getc
+    .extern reset_ioc_read
+    .extern reset_elf_loader
     .extern memcpy
-    .extern boot_puts
-    .extern boot_putx
-    .extern boot_putd
-    .extern boot_ioc_init
+    .extern reset_puts
+    .extern reset_putx
+    .extern reset_putd
+    .extern reset_ioc_init
     .extern versionstr
 
-    .globl  boot                    /* Make reset an external symbol */
-    .ent    boot
+    .globl  reset                    /* Makes reset an external symbol */
+    .ent    reset
 
     .align  2
     .set noreorder
 
-boot:
-    b       _boot                   /* 0xbfc0000 */
+reset:
+    b       _reset                  /* 0xbfc0000 */
     nop                             /* 0xbfc0004 */
 
-    /*  Addresses of the functions provided by this pre-loader */
-
-    .word   BOOT_VERSION            /* 0xbfc0008 */
+    /*  Addresses of the functions provided by this reset code */
+
+    .word   RESET_VERSION           /* 0xbfc0008 */
     .word   dtb_addr                /* 0xbfc000c */
-    .word   boot_putc               /* 0xbfc0010 */
-    .word   boot_getc               /* 0xbfc0014 */
-    .word   boot_ioc_read           /* 0xbfc0018 */
-    .word   boot_elf_loader         /* 0xbfc001C */
+    .word   reset_putc              /* 0xbfc0010 */
+    .word   reset_getc              /* 0xbfc0014 */
+    .word   reset_ioc_read          /* 0xbfc0018 */
+    .word   reset_elf_loader        /* 0xbfc001C */
     .word   memcpy                  /* 0xbfc0020 */
-    .word   boot_puts               /* 0xbfc0024 */
-    .word   boot_putx               /* 0xbfc0028 */
-    .word   boot_putd               /* 0xbfc002C */
-
-_boot:
-    /* Disable interruptions, keep STATUSbev enabled */
+    .word   reset_puts              /* 0xbfc0024 */
+    .word   reset_putx              /* 0xbfc0028 */
+    .word   reset_putd              /* 0xbfc002C */
+
+_reset:
+
+    /* All processors Disable interruptions, keep STATUSbev enabled */
 
     li      k0,     (1 << 22)
     mtc0    k0,     CP0_STATUS
 
-    /* Computes proc_id, local_id, cluster_id, and cluster_increment */
+    /* All processors compute proc_id, local_id, cluster_id, cluster_increment */
 
     mfc0    k0,     CP0_EBASE
@@ -85,46 +99,56 @@
     sll     k1,     t2,     8       /* k1 <= 256*cluster_id                       */
     div     k1,     k0              /* LO <= cluster_id * 256 / NB_CLUSTERS       */
-    mflo    k1                      /* k1 <= physical address extension (8 MSB)   */
-
-    /* Initialization of the count register in the coprocessor 0 */
+    mflo    t7                      /* t7 <= physical address extension (8 MSB)   */
+
+    /* All processors initialise the count register in CP0 */
 
     mtc0    zero,   CP0_COUNT
 
-    /**
-     * Compute the output index for the Write Triggered Interruption mask. 
-     * Each processor enable the WTI for its irq output 
-     * Each processor may have IRQ_PER_PROC private irq outputs from the XICU
-     * In each cluster, the ICU base address depends on the cluster_id 
-     */
-
-    la      t3,     ICU_BASE
-    move    t4,     t1              /* t4 <= local_id                   */
-    li      t5,     IRQ_PER_PROC    /* t5 <= IRQ_PER_PROC               */
+    /*
+     * All processors enable the WTI for XICU 
+     * Each processor may have IRQ_PER_PROC irq outputs from the XICU
+     * In each cluster, the XICU base address depends on the cluster_id 
+     */
+
+    la      t3,     ICU_PADDR_BASE  /* t3 <= ICU base address                     */
+    move    t4,     t1              /* t4 <= local_id                             */
+    li      t5,     IRQ_PER_PROC    /* t5 <= IRQ_PER_PROC                         */
     multu   t4,     t5              
-    mflo    t6                      /* t6 <= IRQ_PER_PROC * local_id    */
-    sll     t4,     t6,     2       /* t4 <= OUT_INDEX = t6 * 4         */
-
-    li      t5,     (0xC << 7)      /* t5 <= FUNC      = XICU_MSK_WTI   */
-    or      t4,     t4,     t5      /* t4 <= FUNC | INDEX | 00          */
-    or      t5,     t3,     t4      /* t5 <= &XICU[MSK_WTI][OUT_INDEX]  */
+    mflo    t6                      /* t6 <= IRQ_PER_PROC * local_id              */
+    sll     t4,     t6,     2       /* t4 <= OUT_INDEX = t6 * 4                   */
+
+    li      t5,     (0xC << 7)      /* t5 <= FUNC      = XICU_MSK_WTI             */
+    or      t4,     t4,     t5      /* t4 <= FUNC | INDEX | 00                    */
+    or      t5,     t3,     t4      /* t5 <= &XICU[MSK_WTI][OUT_INDEX]            */
     
-    /* Compute and set WTI mask using the physical address extension    */
+    /* All processors set WTI mask using the physical address extension    */
 
     li      t4,     1
-    sllv    t4,     t4,     t1      /* Set XICU[MSK_WTI][INDEX][local_id] */
-
-    mtc2    k1,     CP2_PADDR_EXT   /* set PADDR extension                */
-    sw      t4,     0(t3)           /* XICU[MSK_WTI][INDEX] <= t4         */
-    mtc2    zero,   CP2_PADDR_EXT   /* reset PADDR extension              */
-
-    /**
+    sllv    t4,     t4,     t1      /* Set XICU[MSK_WTI][INDEX][local_id]         */
+
+    mtc2    t7,     CP2_PADDR_EXT   /* set PADDR extension                        */
+    sw      t4,     0(t5)           /* XICU[MSK_WTI][INDEX] <= t4                 */
+    mtc2    zero,   CP2_PADDR_EXT   /* reset PADDR extension                      */
+
+    /* All processors initializes stack pointer, depending on proc_id */
+
+   la      k0,      seg_reset_stack_base
+   li      k1,      0x10000         /* k1 <= P0 stack size == 64 Kbytes           */
+   addu    sp,      k0,     k1      /* P0 stack from base to (base + 64K)         */
+
+   li      k1,      0x200           /* k1 <= Pi stack size == 512 bytes           */
+   multu   k1,      t0              
+   mflo    k0                       /* k0 <= 256 * proc_id                        */
+   addu    sp,      sp,     k1
+   addu    sp,      sp,     k0      /* Pi stacks from base + 64K + proc_id*256    */
+
+    /*
+     * Only processor 0 in cluster 0 loads and executes the boot-loader 
      * We have:
-     * t0: global id
-     * t1: local id
+     * t0: global proc_id
+     * t1: local proc_id
      * t2: cluster id
-     * t3: xicu base address
-     * k1: Paddr extension depending on cluster_id
-     * 
-     * Only processor 0 in cluster 0 executes the boot loader 
+     * t3: xicu physical base address in cluster 0
+     * t7: paddr extension depending on cluster_id
      */
 
@@ -132,37 +156,35 @@
     nop
 
-    /* Initializes stack pointer */
-
-    la      sp,     stk
-
-    la      a0,     versionstr
-    la	    k0,     boot_puts
+    /* Processor 0 displays version for this reset code */
+
+#   la      a0,     versionstr
+#   la	    k0,     reset_puts
+#   jalr    k0
+#   nop
+
+
+#ifndef SOCLIB_IOC
+
+    /* Processor 0 Initialize the block device if required */
+
+    la      k0,     reset_ioc_init
     jalr    k0
     nop
 
-#ifndef SOCLIB_IOC
-
-    /* Initialize the block device */
-
-    la      k0,     boot_ioc_init
-    jalr    k0
-    nop
-
 #endif
 
-    /**
-     * Jump to the boot elf loader routine 
-     * Passing as argument the block number in which it must be
-     * the executable elf file to load
-     */
-
-    la      k0,     boot_elf_loader
+    /*
+     * Processor 0 jumps to the reset_elf_loader routine 
+     * Passing as argument the block number in which is loaded the .elf file
+     */
+
+    la      k0,     reset_elf_loader
     li      a0,     BOOT_LOADER_LBA
     jalr    k0
     nop
 
-    /** 
-     * We jump to the entry point address defined in the 
-     * ELF file. This address is returned by boot_elf_loader function.
+    /* 
+     * Processor O jumps to the entry address defined in the .elf file,
+     * and returned by reset_elf_loader function.
      * All function arguments are 0
      */
@@ -175,28 +197,30 @@
     nop
 
-/**
- * Wait in low power consumption mode until the application wakes us.
- * The application wakes up the non-boot CPUs using a IPI with a non-0
- * value in the mailbox. This non-0 value is the address to jump to.
- */
-
-_reset_wait:
-    /**
+    /*
+     * All processor (but processor 0) wait in low power mode 
+     * until processor 0 wakes them using an IPI.
      * We have:
      * t0: global id
      * t1: local id
      * t2: cluster id
-     * t3: xicu base address
-     * k1: Paddr extension depending on cluster_id
-     */
-
-    sll     t4,     t1,     2       /* t4 <= local_id * 4             */
-    addu    t5,     t4,     t3      /* t5 <= &XICU[WTI_REG][local_id] */
+     * t3: xicu physical base address in cluster 0
+     * t7: Paddr extension depending on cluster_id
+     */
+
+_reset_wait:
+
+    sll     t4,     t1,     2       /* t4 <= local_id * 4                 */
+    addu    t5,     t4,     t3      /* t5 <= &XICU[WTI_REG][local_id]     */
 
     wait
 
-    /* read the address to jump with a physical read */
-
-    mtc2    k1,     CP2_PADDR_EXT   /* set PADDR extension                */
+    /* 
+     * All other processors, when exiting wait mode,
+     * read from XICU the address to jump.
+     * This address is the boot-loader entry address that has been
+     * written in the mailbox by the IPI sent by processor 0
+     */
+
+    mtc2    t7,     CP2_PADDR_EXT   /* set PADDR extension                */
     lw      k0,     0(t5)           /* k0 <= XICU[WTI_REG][local_id]      */
     mtc2    zero,   CP2_PADDR_EXT   /* reset PADDR extension              */
@@ -206,21 +230,17 @@
 
 /* Exception entry point */
+
 .org 0x0380
 _excep:
-    mfc0    a0, CP0_STATUS          /* first arg is status */
-    mfc0    a1, CP0_CAUSE           /* second arg is cause */
-    mfc0    a2, CP0_EPC             /* third argc is epc   */
+    mfc0    a0, CP0_STATUS          /* first arg is status                */
+    mfc0    a1, CP0_CAUSE           /* second arg is cause                */
+    mfc0    a2, CP0_EPC             /* third argc is epc                  */
     nop
     j       handle_except
     nop
 
-    .end boot
+    .end reset
 
     .set reorder
-
-    .section .data
-    .space BOOT_STACK_SIZE
-stk:
-    .space 1
 
 /*
Index: /trunk/softs/tsar_boot/src/reset_elf_loader.c
===================================================================
--- /trunk/softs/tsar_boot/src/reset_elf_loader.c	(revision 586)
+++ /trunk/softs/tsar_boot/src/reset_elf_loader.c	(revision 586)
@@ -0,0 +1,340 @@
+/**
+ * \file    : reset_elf_loader.c
+ * \date    : August 2012
+ * \author  : Cesar Fuguet
+ *
+ * This file defines an elf file loader which reads an executable .elf file
+ * starting at a sector passed as argument on a disk and copy the different
+ * ELF program segments in the appropriate memory address using as information
+ * the virtual address read from the .elf file.
+ */
+
+#include <reset_ioc.h>
+#include <elf-types.h>
+#include <reset_tty.h>
+#include <reset_utils.h>
+#include <defs.h>
+
+#if (RESET_DEBUG == 1)
+static char const * const init_state_str[] = 
+{
+    "ELF_HEADER_STATE",
+    "ELF_PROGRAM_HEADER_STATE",
+    "ELF_OFFSET_STATE",
+    "ELF_SEGMENT_STATE",
+    "ELF_END_STATE"
+};
+#endif
+
+unsigned char reset_elf_loader_buffer[512] __attribute__((aligned(CACHE_LINE_SIZE)));
+
+/////////////////////////////////////////////////////////////////////////////////////
+void * reset_elf_loader(unsigned int lba)
+/////////////////////////////////////////////////////////////////////////////////////
+{
+    /*
+     * Temporary variables used by the loader
+     */
+    Elf32_Ehdr      elf_header;
+    Elf32_Phdr      elf_pht[PHDR_ARRAY_SIZE];
+
+    unsigned char * buffer_ptr;
+    Elf32_Ehdr    * elf_ehdr_ptr;
+    Elf32_Phdr    * elf_phdr_ptr;
+
+    unsigned int nb_available;
+    unsigned int nb_rest;
+    unsigned int nb_read;
+    unsigned int nb_block;
+    unsigned int offset;
+
+    unsigned char * pseg_ptr;
+    unsigned int pseg_start;
+    unsigned int pseg_end;
+    unsigned int pseg_remainder;
+    unsigned int pseg;
+
+    /*
+     * Loader state machine definition
+     */
+    typedef enum
+    {
+        ELF_HEADER_STATE,
+        ELF_PROGRAM_HEADER_STATE,
+        ELF_OFFSET_STATE,
+        ELF_SEGMENT_STATE,
+        ELF_END_STATE
+    } elf_loader_t;
+
+    elf_loader_t init_state;
+    init_state = ELF_HEADER_STATE;
+
+#if (RESET_DEBUG == 1)
+    elf_loader_t init_state_debug;
+    init_state_debug = ELF_END_STATE;
+#endif
+
+    reset_puts("\n[RESET] Start reset_elf_loader at cycle ");
+    reset_putd( proctime() );
+    reset_puts("\n");
+
+    nb_block     = lba;
+    nb_available = 0;
+    nb_rest      = sizeof(Elf32_Ehdr);
+    pseg         = 0;
+    offset       = 0;
+    elf_ehdr_ptr = (Elf32_Ehdr *) &elf_header;
+    elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0];
+
+    while(init_state != ELF_END_STATE)
+    {
+        if (nb_available == 0 )
+        {
+            buffer_ptr = &reset_elf_loader_buffer[0];
+
+            if (reset_ioc_read(nb_block , buffer_ptr, 1))
+            {
+                reset_puts ("[RESET ERROR] reset_ioc_read() failed\n");
+                reset_exit();
+            }
+
+            nb_block    += 1;
+            nb_available = 512;
+        }
+
+        nb_read  = (nb_rest <= nb_available) ? nb_rest : nb_available;
+        offset  +=  nb_read;
+
+#if (RESET_DEBUG == 1)
+        if (init_state != init_state_debug)
+        {
+            reset_puts("\ninit_state = ");
+            reset_puts(init_state_str[init_state]);
+            reset_puts("\n");
+            init_state_debug = init_state;
+        }
+#endif
+
+        switch(init_state)
+        {
+            /*
+             * Reading ELF executable header
+             */
+            case ELF_HEADER_STATE:
+                memcpy(elf_ehdr_ptr, buffer_ptr, nb_read);
+
+                nb_rest -= nb_read;
+
+                if(nb_rest == 0)
+                {
+                    nb_rest = elf_ehdr_ptr->e_phnum * elf_ehdr_ptr->e_phentsize;
+                    /*
+                     * Verification of ELF Magic Number
+                     */
+                    if ( (elf_ehdr_ptr->e_ident[EI_MAG0] != ELFMAG0) ||
+                         (elf_ehdr_ptr->e_ident[EI_MAG1] != ELFMAG1) ||
+                         (elf_ehdr_ptr->e_ident[EI_MAG2] != ELFMAG2) ||
+                         (elf_ehdr_ptr->e_ident[EI_MAG3] != ELFMAG3) )
+                    {
+                        reset_puts("[RESET ERROR] boot-loader file is not an ELF format\n");
+                        reset_exit();
+                    }
+
+                    /*
+                     * Verification of Program Headers table size. It must be
+                     * smaller than the work size allocated for the
+                     * elf_pht[PHDR_ARRAY_SIZE] array
+                     */
+                    if (elf_ehdr_ptr->e_phnum > PHDR_ARRAY_SIZE)
+                    {
+                        reset_puts("[RESET ERROR] ELF PHDR table size too large\n");
+                        reset_exit();
+                    }
+
+                    init_state = ELF_PROGRAM_HEADER_STATE;
+                }
+
+                break;
+
+            /*
+             * Reading ELF program headers
+             */
+            case ELF_PROGRAM_HEADER_STATE:
+                memcpy(elf_phdr_ptr, buffer_ptr, nb_read);
+
+                elf_phdr_ptr = 
+                    (Elf32_Phdr *)((unsigned char *) elf_phdr_ptr + nb_read);
+
+                nb_rest -= nb_read;
+
+                if(nb_rest == 0)
+                {
+                    elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0];
+
+                    /*
+                     * Search the first not NULL segment in the ELF file
+                     */
+                    for (pseg = 0; pseg < elf_ehdr_ptr->e_phnum; pseg++)
+                    {
+                        if(elf_phdr_ptr[pseg].p_type == PT_LOAD)
+                        {
+#if (RESET_DEBUG == 1)
+                            reset_puts("loadable segment found:\n");
+                            reset_print_elf_phdr(&elf_phdr_ptr[pseg]);
+#endif
+                            if (elf_phdr_ptr[pseg].p_offset < offset)
+                            {
+                                /* 
+                                 * Case where the segment to load includes the 
+                                 * elf and program headers 
+                                 */
+                                nb_rest = elf_phdr_ptr[pseg].p_filesz - offset;
+                                init_state = ELF_SEGMENT_STATE;
+                            }
+                            else
+                            {
+                                /* 
+                                 * Segment to load is further away in ELF file
+                                 */
+                                nb_rest = elf_phdr_ptr[pseg].p_offset - offset;
+                                init_state = ELF_OFFSET_STATE;
+                            }
+                            break;
+                        }
+                    }
+
+                    if (pseg == elf_ehdr_ptr->e_phnum)
+                    {
+                        reset_puts("[RESET ERROR] No PT_LOAD found\n");
+                        reset_exit();
+                    }
+
+                }
+
+                break;
+
+            /*
+             * Go to the offset of the first not null program segment in the
+             * ELF file
+             *
+             * TODO:
+             * No need to read from the disk the useless bytes. Try to compute
+             * the next usefull lba
+             */
+            case ELF_OFFSET_STATE:
+                nb_rest -= nb_read;
+
+                if (nb_rest == 0)
+                {
+                    nb_rest    = elf_phdr_ptr[pseg].p_filesz;
+                    init_state = ELF_SEGMENT_STATE;
+                }
+
+                break;
+
+            /*
+             * Reading ELF segments
+             *
+             * TODO:
+             * Do not pass by block buffer but write directly in target memory
+             * address
+             */
+            case ELF_SEGMENT_STATE:
+                /*
+                 * Verify that loadable segment does not conflict with
+                 * pre-loader memory space 
+                 */
+                pseg_start = elf_phdr_ptr[pseg].p_vaddr;
+
+                pseg_end   = elf_phdr_ptr[pseg].p_vaddr +
+                             elf_phdr_ptr[pseg].p_memsz;
+
+                if ((pseg_start >= 0xBFC00000 && pseg_start <= 0xBFC10000) ||
+                    (pseg_end   >= 0xBFC00000 && pseg_end   <= 0xBFC10000) ||
+                    (pseg_start <  0xBFC00000 && pseg_end   >  0xBFC10000))
+                {
+                    reset_puts("[RESET ERROR] conflict with pre-loader memory space\n");
+                    reset_exit();
+                }
+
+                /*
+                 * Copy the ELF segment data in memory using the
+                 * virtual address obtained from the ELF file
+                 */
+                pseg_ptr = (unsigned char *)
+                    elf_phdr_ptr[pseg].p_vaddr  +
+                    elf_phdr_ptr[pseg].p_filesz -
+                    nb_rest;
+
+                memcpy(pseg_ptr, buffer_ptr, nb_read);
+
+                nb_rest -= nb_read;
+
+                if (nb_rest == 0)
+                {
+                    /*
+                     * Fill remaining bytes with zeros (filesz < memsz)
+                     */
+                    pseg_remainder =
+                        elf_phdr_ptr[pseg].p_memsz  -
+                        elf_phdr_ptr[pseg].p_filesz ;
+
+                    pseg_ptr = (unsigned char *)
+                        elf_phdr_ptr[pseg].p_vaddr  +
+                        elf_phdr_ptr[pseg].p_filesz ;
+
+//                  memset(pseg_ptr, 0, pseg_remainder);
+
+                    reset_puts("\n[RESET] Segment loaded : address = ");
+                    reset_putx(elf_phdr_ptr[pseg].p_vaddr);
+                    reset_puts(" / size = ");
+                    reset_putx(elf_phdr_ptr[pseg].p_filesz);
+                    reset_puts("\n");
+
+                    /*
+                     * Search the next first not NULL segment in the ELF file
+                     */
+                    for (pseg += 1; pseg < elf_ehdr_ptr->e_phnum; pseg++)
+                    {
+                        if(elf_phdr_ptr[pseg].p_type == PT_LOAD)
+                        {
+#if (RESET_DEBUG == 1)
+                            reset_puts("loadable segment found:\n");
+                            reset_print_elf_phdr(&elf_phdr_ptr[pseg]);
+#endif
+                            nb_rest = elf_phdr_ptr[pseg].p_offset - offset;
+                            break;
+                        }
+                    }
+
+                    /*
+                     * Program loading finished
+                     */
+                    if(pseg == elf_ehdr_ptr->e_phnum)
+                    {
+                        init_state = ELF_END_STATE;
+                        break;
+                    }
+
+                    init_state = ELF_OFFSET_STATE;
+                }
+                break;
+
+            default:
+                break;
+        }
+
+        buffer_ptr   += nb_read;
+        nb_available -= nb_read;
+    }
+
+    reset_puts("\n[RESET] Complete reset_elf_loader at cycle ");
+    reset_putd( proctime() );
+    reset_puts(" / boot entry = ");
+    reset_putx( (unsigned int)(elf_ehdr_ptr->e_entry) );
+    reset_puts("\n");
+
+    return ((void *) elf_ehdr_ptr->e_entry);
+}
+
+// vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
Index: /trunk/softs/tsar_boot/src/reset_exception.c
===================================================================
--- /trunk/softs/tsar_boot/src/reset_exception.c	(revision 586)
+++ /trunk/softs/tsar_boot/src/reset_exception.c	(revision 586)
@@ -0,0 +1,23 @@
+/**
+ * \file    : exceptions.c
+ * \date    : December 2012
+ * \author  : Manuel Bouyer
+ *
+ * This file defines a simple exceptions handler
+ */
+
+#include <reset_tty.h>
+
+void handle_except(int status, int cause, int epc)
+{
+	reset_puts("\n[RESET] exception handler called: \r\n    status ");
+	reset_putx(status);
+	reset_puts("\r\n    cause  ");
+	reset_putx(cause);
+	reset_puts(" (exception ");
+	reset_putx((cause >> 2) & 0x1f);
+	reset_puts(")\r\n    epc    ");
+	reset_putx(epc);
+	reset_puts("\r\n");
+	while (1);
+}
Index: /trunk/softs/tsar_boot/src/reset_ioc.c
===================================================================
--- /trunk/softs/tsar_boot/src/reset_ioc.c	(revision 586)
+++ /trunk/softs/tsar_boot/src/reset_ioc.c	(revision 586)
@@ -0,0 +1,306 @@
+#include <reset_ioc.h>
+
+#ifndef SOCLIB_IOC
+
+static struct sdcard_dev        _sdcard_device;
+static struct spi_dev   *const  _spi_device   = ( struct spi_dev * )IOC_BASE;
+
+#endif
+
+#define SDCARD_RESET_ITER_MAX   4
+
+///////////////////////////////////
+inline void reset_sleep(int cycles)
+{
+    int i;
+    for (i = 0; i < cycles; i++);
+}
+
+#if RESET_DEBUG 
+////////////////////////////////////
+inline unsigned int reset_proctime()
+{
+    unsigned int ret;
+    asm volatile ("mfc0 %0, $9":"=r" (ret));
+    return ret;
+}
+#endif
+
+#ifndef SOCLIB_IOC
+/////////////////////////////////////////////////////////////////////////////////
+//     reset_ioc_init
+// This function initializes the SDCARD / required for FPGA.
+/////////////////////////////////////////////////////////////////////////////////
+int reset_ioc_init()
+{
+    unsigned char sdcard_rsp;
+
+    reset_puts("Initializing block device\n\r");
+
+    /**
+     * Initializing the SPI controller
+     */
+    spi_dev_config (
+      _spi_device   ,
+      200000        , /**< SPI_clk: 200 Khz */
+      SYSCLK_FREQ   , /**< Sys_clk          */
+      8             , /**< Charlen: 8       */
+      SPI_TX_NEGEDGE,
+      SPI_RX_POSEDGE
+    );
+
+    /**
+     * Initializing the SD Card
+     */
+    unsigned int iter = 0;
+    while(1)
+    {
+        reset_puts("Trying to initialize SD card... ");
+
+        sdcard_rsp = sdcard_dev_open(&_sdcard_device, _spi_device, 0);
+        if (sdcard_rsp == 0)
+        {
+            reset_puts("OK\n");
+            break;
+        }
+
+        reset_puts("KO\n");
+        reset_sleep(1000);
+        if (++iter >= SDCARD_RESET_ITER_MAX)
+        {
+            reset_puts("\nERROR: During SD card reset to IDLE state\n"
+                      "/ card response = ");
+            reset_putx(sdcard_rsp);
+            reset_puts("\n");
+            reset_exit();
+        }
+    }
+
+    /**
+     * Set the block length of the SD Card
+     */
+    sdcard_rsp = sdcard_dev_set_blocklen(&_sdcard_device, 512);
+    if (sdcard_rsp)
+    {
+        reset_puts("ERROR: During SD card blocklen initialization\n");
+        reset_exit();
+    }
+
+    /**
+     * Incrementing SDCARD clock frequency for normal function
+     */
+    spi_dev_config (
+        _spi_device ,
+        10000000    , /**< SPI_clk 10 Mhz */
+        SYSCLK_FREQ , /**< Sys_clk        */
+        -1          , /**< Charlen: 8     */
+        -1          ,
+        -1
+    );
+
+    reset_puts("Finish block device initialization\n\r");
+
+    return 0;
+} // end reset_ioc_init()
+#endif 
+
+#ifdef SOCLIB_IOC
+/////////////////////////////////////////////////////////////////////////////////////
+//      reset_ioc_completed()
+// This blocking function checks completion of an I/O transfer and reports errors.
+// It returns 0 if the transfer is successfully completed.
+// It returns -1 if an error has been reported.
+/////////////////////////////////////////////////////////////////////////////////////
+int reset_ioc_completed()
+{
+    unsigned int status = 0;
+
+    unsigned int * ioc_address = ( unsigned int * )IOC_PADDR_BASE;
+
+    while ( 1 )
+    {
+        status = ioread32(&ioc_address[BLOCK_DEVICE_STATUS]);
+
+        if (( status == BLOCK_DEVICE_READ_SUCCESS ) ||
+            ( status == BLOCK_DEVICE_READ_ERROR  ))
+        break;
+    }
+
+    return status;
+} // end reset_ioc_completed()
+#endif
+
+#ifdef SOCLIB_IOC
+/////////////////////////////////////////////////////////////////////////////////////
+//      reset_ioc_read()
+// Transfer data the block device to a memory buffer: SOCLIB version
+// - param lba    : first block index on the disk
+// - param buffer : base address of the memory buffer
+// - param count  : number of blocks to be transfered
+// This is a blocking function. The function returns once the transfer is completed.
+/////////////////////////////////////////////////////////////////////////////////////
+int reset_ioc_read( unsigned int lba, 
+                    void*        buffer, 
+                    unsigned int count )
+{
+
+    unsigned int * ioc_address  = (unsigned int*)IOC_PADDR_BASE;
+
+#if RESET_DEBUG 
+    unsigned int start_time;
+    unsigned int end_time;
+    reset_puts("[RESET DEBUG] Reading blocks ");
+    reset_putd(lba);
+    reset_puts(" to ");
+    reset_putd(lba + count - 1);
+
+    start_time = reset_proctime();
+#endif
+
+    // block_device configuration
+    iowrite32( &ioc_address[BLOCK_DEVICE_BUFFER],
+            ( unsigned int ) buffer );
+
+    iowrite32( &ioc_address[BLOCK_DEVICE_COUNT],
+            ( unsigned int ) count );
+
+    iowrite32( &ioc_address[BLOCK_DEVICE_LBA],
+            ( unsigned int ) lba );
+
+    iowrite32( &ioc_address[BLOCK_DEVICE_IRQ_ENABLE],
+            ( unsigned int ) 0 );
+
+    iowrite32( &ioc_address[BLOCK_DEVICE_OP],
+            ( unsigned int ) BLOCK_DEVICE_READ );
+
+    reset_ioc_completed();
+
+#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
+    reset_buf_invalidate(buffer, CACHE_LINE_SIZE, count * 512);
+#endif
+
+#if USE_IOB 
+    reset_mcc_invalidate(buffer, count * 512);
+#endif
+
+#if RESET_DEBUG 
+    end_time = reset_proctime();
+    reset_puts(" / cycles for transfert: ");
+    reset_putd(end_time - start_time);
+    reset_puts("\n");
+#endif
+
+    return 0;
+} // end reset_ioc_read()
+
+#else
+
+/////////////////////////////////////////////////////////////////////////////////////
+//      reset_ioc_read()
+// Transfer data the block device to a memory buffer: FPGA version
+// - param lba    : first block index on the disk
+// - param buffer : base address of the memory buffer
+// - param count  : number of blocks to be transfered
+// This is a blocking function. The function returns once the transfer is completed.
+/////////////////////////////////////////////////////////////////////////////////////
+int reset_ioc_read( unsigned int lba, 
+                    void*        buffer, 
+                    unsigned int count )
+{
+    unsigned int sdcard_rsp;
+    unsigned int i;
+
+    sdcard_dev_lseek(&_sdcard_device, lba);
+
+#if RESET_DEBUG 
+    unsigned int start_time;
+    unsigned int end_time;
+    reset_puts("[RESET DEBUG] Reading blocks ");
+    reset_putd(lba);
+    reset_puts(" to ");
+    reset_putd(lba + count - 1);
+    start_time = reset_proctime();
+#endif
+
+    for(i = 0; i < count; i++)
+    {
+        if (( sdcard_rsp = sdcard_dev_read (
+                        &_sdcard_device,
+                        (unsigned char *) buffer + (512 * i),
+                        512
+                        )
+            ))
+        {
+            reset_puts("ERROR during read on the SDCARD device. Code: ");
+            reset_putx(sdcard_rsp);
+            reset_puts("\n\r");
+
+            return 1;
+        }
+    }
+
+#if RESET_DEBUG
+    end_time = reset_proctime();
+    reset_puts(" / cycles for transfert: ");
+    reset_putd(end_time - start_time);
+    reset_puts("\n");
+#endif
+
+    return 0;
+} // end reset_ioc_read()
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// reset_dcache_buf_invalidate()
+// Invalidate all data cache lines corresponding to a memory buffer
+// (identified by an address and a size) in L1 cache.
+/////////////////////////////////////////////////////////////////////////////
+#if (CACHE_COHERENCE == 0) || (USE_IOB == 1)
+void reset_buf_invalidate ( const void * buffer,
+                            unsigned int line_size,
+                            unsigned int size)
+{
+    unsigned int i;
+
+    // iterate on cache lines
+    for (i = 0; i <= size; i += line_size) 
+    {
+        asm volatile(
+            " cache %0, %1"
+            :// no outputs
+            :"i" (0x11), "R" (*((unsigned char *) buffer + i))
+            );
+    }
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// reset_mcc_inval()
+// Invalidate all data cache lines corresponding to a memory buffer
+// (identified by an address and a size) in L2 cache.
+/////////////////////////////////////////////////////////////////////////////
+#if USE_IOB 
+void reset_mcc_invalidate ( const void * buffer,
+                            unsigned int size)
+{
+    unsigned int * mcc_address = (unsigned int *)MCC_PADDR_BASE;
+
+    // get the hard lock assuring exclusive access to MEMC
+    while (ioread32(&mcc_address[MCC_LOCK]));
+
+    // write invalidate paremeters on the memory cache
+    // this preloader use only the cluster 0 and then the HI bits are not used
+    
+    iowrite32(&mcc_address[MCC_ADDR_LO], (unsigned int) buffer);
+    iowrite32(&mcc_address[MCC_ADDR_HI], (unsigned int) 0);
+    iowrite32(&mcc_address[MCC_LENGTH] , (unsigned int) size);
+    iowrite32(&mcc_address[MCC_CMD]    , (unsigned int) MCC_CMD_INVAL);
+
+    // release the lock protecting MEMC
+    iowrite32(&mcc_address[MCC_LOCK], (unsigned int) 0);
+}
+#endif
+
+/*
+ * vim: tabstop=4 : shiftwidth=4 : expandtab
+ */
Index: /trunk/softs/tsar_boot/src/reset_tty.c
===================================================================
--- /trunk/softs/tsar_boot/src/reset_tty.c	(revision 586)
+++ /trunk/softs/tsar_boot/src/reset_tty.c	(revision 586)
@@ -0,0 +1,100 @@
+#include <reset_tty.h>
+#include <io.h>
+#include <defs.h>
+
+///////////////////////
+int reset_getc(char *c)
+{
+    unsigned int* tty_address = (unsigned int*) TTY_PADDR_BASE;
+    if (ioread32(&tty_address[TTY_STATUS]) == 0)
+        return 0;
+
+    *c = ioread32(&tty_address[TTY_READ]);
+    return 1;
+}
+
+/////////////////////////////
+void reset_putc(const char c)
+{
+    unsigned int* tty_address = (unsigned int*) TTY_PADDR_BASE;
+    iowrite32(&tty_address[TTY_WRITE], (unsigned int)c);
+
+    if (c == '\n')
+    {
+        iowrite32(&tty_address[TTY_WRITE], (unsigned int)'\r');
+    }
+}
+
+///////////////////////////////////
+void reset_puts(const char *buffer) 
+{
+    unsigned int n;
+
+    for ( n=0; n<100; n++)
+    {
+        if (buffer[n] == 0) break;
+
+        reset_putc(buffer[n]);
+    }
+} 
+
+/////////////////////////////////
+void reset_putx(unsigned int val)
+{
+    static const char HexaTab[] = "0123456789ABCDEF";
+    char              buf[11];
+    unsigned int      c;
+
+    buf[0]  = '0';
+    buf[1]  = 'x';
+    buf[10] = 0;
+
+    for ( c = 0 ; c < 8 ; c++ )
+    { 
+        buf[9-c] = HexaTab[val&0xF];
+        val = val >> 4;
+    }
+    reset_puts(buf);
+}
+
+/////////////////////////////////
+void reset_putd(unsigned int val)
+{
+    static const char DecTab[] = "0123456789";
+    char              buf[11];
+    unsigned int      i;
+    unsigned int      first = 0;
+
+    buf[10] = 0;
+
+    for ( i = 0 ; i < 10 ; i++ )
+    {
+        if ((val != 0) || (i == 0))
+        {
+            buf[9-i] = DecTab[val % 10];
+            first    = 9-i;
+        }
+        else
+        {
+            break;
+        }
+        val /= 10;
+    }
+    reset_puts( &buf[first] );
+}
+
+/////////////////
+void reset_exit()
+{
+    register int pid;
+    asm volatile( "mfc0 %0, $15, 1": "=r"(pid) );
+
+    reset_puts("\n!!! Exit Processor ");
+    reset_putx(pid);
+    reset_puts(" !!!\n");
+
+    while(1) asm volatile("nop");   // infinite loop...
+}
+
+
+
Index: /trunk/softs/tsar_boot/src/reset_utils.c
===================================================================
--- /trunk/softs/tsar_boot/src/reset_utils.c	(revision 586)
+++ /trunk/softs/tsar_boot/src/reset_utils.c	(revision 586)
@@ -0,0 +1,108 @@
+/**
+ * \file    : reset_utils.c
+ * \date    : August 2012
+ * \author  : Cesar Fuguet
+ *
+ * Definition of utilities functions used by the TSAR pre-loader
+ */
+
+#include <reset_utils.h>
+
+/*****************************************
+ * proctime()
+ *
+ * Returns processor local time.
+ ****************************************/
+inline unsigned int proctime() 
+{
+    unsigned int ret;
+    asm volatile ("mfc0   %0,        $9":"=r" (ret));
+    return ret;
+}
+
+/*****************************************
+ * memcpy( _dst, _src, size )
+ *
+ * Transfer data between two memory buffers.
+ *
+ * \param _dst   : Destination buffer base address 
+ * \param _src   : Source buffer base address
+ * \param size   : Number of bytes to transfer 
+ *
+ ****************************************/
+void * memcpy(void *_dst, const void *_src, unsigned int size)
+{
+    unsigned int *dst = _dst;
+    const unsigned int *src = _src;
+    if ( ! ((unsigned int)dst & 3) && ! ((unsigned int)src & 3) )
+        while (size > 3) 
+        {
+            *dst++ = *src++;
+            size -= 4;
+        }
+
+    unsigned char *cdst = (unsigned char*) dst;
+    unsigned char *csrc = (unsigned char*) src;
+
+    while (size--) 
+    {
+        *cdst++ = *csrc++;
+    }
+    return _dst;
+}
+
+/*****************************************
+ * memset( _dst, value, size )
+ *
+ * Initialize memory buffers with predefined value.
+ *
+ * \param _dst   : Destination buffer base address 
+ * \param value  : Initialization value 
+ * \param size   : Number of bytes to initialize
+ *
+ ****************************************/
+void * memset(void *_dst, const int value, unsigned int size)
+{
+    char * dst = (char *) _dst;
+
+    while(size--) *dst++ = (char) value;
+
+    return _dst;
+}
+
+/*****************************************
+ * reset_print_elf_phdr( elf_phdr_ptr )
+ *
+ * Print some fields of a ELF program header
+ *
+ * \param elf_phdr_ptr : Pointer to the ELF program header to print
+ *
+ ****************************************/
+void reset_print_elf_phdr(Elf32_Phdr * elf_phdr_ptr)
+{
+    reset_puts("- type   : ");
+    reset_putx(elf_phdr_ptr->p_type);
+
+    reset_puts("\n- offset : ");
+    reset_putx(elf_phdr_ptr->p_offset);
+
+    reset_puts("\n- vaddr  : ");
+    reset_putx(elf_phdr_ptr->p_vaddr);
+
+    reset_puts("\n- paddr  : ");
+    reset_putx(elf_phdr_ptr->p_paddr);
+
+    reset_puts("\n- filesz : ");
+    reset_putx(elf_phdr_ptr->p_filesz);
+
+    reset_puts("\n- memsz  : ");
+    reset_putx(elf_phdr_ptr->p_memsz);
+
+    reset_puts("\n- flags  : ");
+    reset_putx(elf_phdr_ptr->p_flags);
+
+    reset_puts("\n- align  : ");
+    reset_putx(elf_phdr_ptr->p_align);
+}
+
+// vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab
Index: /trunk/softs/tsar_boot/src/sdcard.c
===================================================================
--- /trunk/softs/tsar_boot/src/sdcard.c	(revision 585)
+++ /trunk/softs/tsar_boot/src/sdcard.c	(revision 586)
@@ -8,5 +8,5 @@
 
 #include <sdcard.h>
-#include <boot_tty.h>
+#include <reset_tty.h>
 
 /**
@@ -184,5 +184,5 @@
 	if ( sdcard_rsp != 0x01 )
 	{
-		boot_puts("card CMD0 failed ");
+		reset_puts("card CMD0 failed ");
 		return sdcard_rsp;
 	}
@@ -200,5 +200,5 @@
 	sdcard_rsp = _sdcard_send_command(sdcard, 8, SDCARD_CMD, args, 0x63);
 	if (!SDCARD_CHECK_R1_VALID(sdcard_rsp)) {
-		boot_puts("card CMD8 failed ");
+		reset_puts("card CMD8 failed ");
 		return sdcard_rsp;
 	}
@@ -211,13 +211,13 @@
 		if ((ersp & 0xffff) != 0x0101) {
 			/* voltage mismatch */
-			boot_puts("card CMD8 mismatch: ");
-			boot_putx(ersp);
+			reset_puts("card CMD8 mismatch: ");
+			reset_putx(ersp);
 			return sdcard_rsp;
 		}
-		boot_puts("v2 or later ");
+		reset_puts("v2 or later ");
 		sdcard->sdhc = 1;
 	} else if ((sdcard_rsp & SDCARD_R1_ILLEGAL_CMD) == 0) {
 		/* other error */
-		boot_puts("card CMD8 error ");
+		reset_puts("card CMD8 error ");
 		return sdcard_rsp;
 	} else {
@@ -246,5 +246,5 @@
 	_sdcard_disable(sdcard);
 	if (sdcard_rsp) {
-		boot_puts("SD ACMD41 failed ");
+		reset_puts("SD ACMD41 failed ");
 		return sdcard_rsp;
 	}
@@ -259,5 +259,5 @@
 		    args, 0x00);
 		if (sdcard_rsp) {
-			boot_puts("SD CMD58 failed ");
+			reset_puts("SD CMD58 failed ");
 			return sdcard_rsp;
 		}
@@ -267,5 +267,5 @@
 		ersp = (ersp << 8) | _sdcard_receive_char(sdcard);
 		if (ersp & 0x40000000) {
-			boot_puts("SDHC ");
+			reset_puts("SDHC ");
 		} else {
 			sdcard->sdhc = 0;
@@ -273,5 +273,5 @@
 		_sdcard_disable(sdcard);
 	}
-	boot_puts("card detected ");
+	reset_puts("card detected ");
 	return 0;
 }
