Index: /branch/giet_vm_ioc_drivers/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/Makefile	(revision 283)
@@ -0,0 +1,415 @@
+export # export all variable to sub-Makefile
+CC = mipsel-unknown-elf-gcc
+AS = mipsel-unknown-elf-as
+LD = mipsel-unknown-elf-ld
+DU = mipsel-unknown-elf-objdump
+
+### FAT parameters definition for Disk image
+### sector_size          = 512
+### partition_begin_lba  = 300
+### sector_per_cluster   = 8
+### partition sectors    = 524832 
+
+MAP_XML      = mappings/4c_1p_four.xml
+
+### Objects to be linked for kernel.elf
+KERNEL_OBJS  = build/common/utils.o        \
+               build/common/vmem.o          \
+               build/fat32/fat32.o        \
+               build/drivers/dma_driver.o \
+               build/drivers/fbf_driver.o \
+               build/drivers/xcu_driver.o \
+               build/drivers/icu_driver.o \
+               build/drivers/ioc_driver.o \
+               build/drivers/bdv_driver.o \
+               build/drivers/sdc_driver.o \
+               build/drivers/spi_driver.o \
+               build/drivers/iob_driver.o \
+               build/drivers/mmc_driver.o \
+               build/drivers/mwr_driver.o \
+               build/drivers/nic_driver.o \
+               build/drivers/tim_driver.o \
+               build/drivers/tty_driver.o \
+               build/kernel/giet.o        \
+               build/kernel/switch.o      \
+               build/kernel/ctx_handler.o \
+               build/kernel/exc_handler.o \
+               build/kernel/sys_handler.o \
+               build/kernel/irq_handler.o \
+               build/kernel/kernel_init.o
+
+### Objects to be linked for boot.elf
+BOOT_OBJS    = build/common/utils.o        \
+               build/common/vmem.o          \
+               build/fat32/fat32.o        \
+               build/drivers/tty_driver.o \
+               build/drivers/xcu_driver.o \
+               build/drivers/dma_driver.o \
+               build/drivers/mwr_driver.o \
+               build/drivers/ioc_driver.o \
+               build/drivers/bdv_driver.o \
+               build/drivers/sdc_driver.o \
+               build/drivers/spi_driver.o \
+               build/drivers/nic_driver.o \
+               build/drivers/mmc_driver.o \
+               build/kernel/ctx_handler.o \
+               build/kernel/switch.o      \
+               build/boot/boot.o 
+
+### Objects to be linked for display.elf
+DISPLAY_OBJS = build/display/main.o \
+               build/libs/stdio.o
+
+### Objects to be linked for router.elf
+ROUTER_OBJS  = build/router/main.o        \
+               build/libs/mwmr_channel.o  \
+               build/libs/stdio.o 
+
+### Objects to be linked for hello.elf
+HELLO_OBJS   = build/hello/main.o   \
+               build/libs/stdio.o         
+
+### Objects to be linked for pgcd.elf
+PGCD_OBJS    = build/pgcd/main.o          \
+               build/libs/stdio.o 
+
+### Objects to be linked for game.elf
+GAMEOFLIFE_OBJS = build/gameoflife/main.o \
+                  build/libs/stdio.o      \
+                  build/libs/barrier.o
+
+### Objects to be linked for dhrystone.elf
+DHRYSTONE_OBJS = build/dhrystone/dhry_1.o \
+                 build/dhrystone/dhry_2.o \
+                 build/libs/stdlib.o      \
+                 build/libs/stdio.o       \
+                 build/libs/string.o      \
+                 build/libs/spin_lock.o   \
+                 build/libs/malloc.o
+
+### Objects to be linked for sort.elf
+SORT_OBJS   = build/sort/main.o        \
+              build/libs/stdio.o       \
+              build/libs/spin_lock.o   \
+              build/libs/barrier.o
+
+
+CFLAGS = -Wall -ffreestanding -mno-gpopt -mips32# -O3 -fno-inline
+
+
+GIET_INCLUDE = -Igiet_boot    \
+               -Igiet_kernel  \
+               -Igiet_xml     \
+               -Igiet_fat32   \
+               -Igiet_drivers \
+               -Igiet_common  \
+               -Igiet_libs    \
+               -I.
+
+USER_INCLUDE = -Igiet_libs    \
+               -Igiet_xml     \
+               -I.
+
+all: map.bin                         \
+     build/boot/boot.elf             \
+     build/kernel/kernel.elf         \
+     build/display/display.elf       \
+     build/router/router.elf         \
+     build/hello/hello.elf           \
+     build/pgcd/pgcd.elf             \
+     build/dhrystone/dhrystone.elf   \
+     build/gameoflife/gameoflife.elf \
+     build/sort/sort.elf             \
+     hdd/virt_hdd.dmg
+
+### Disk image generation
+### This requires the generic LINUX/MacOS script "create_dmg" script 
+### written by C.Fuguet. (should be installed in GIET-VM root directory).
+hdd/virt_hdd.dmg: map.bin                   \
+         build/boot/boot.elf            \
+         build/kernel/kernel.elf        \
+         build/display/display.elf      \
+         build/hello/hello.elf          \
+         build/pgcd/pgcd.elf            \
+         build/router/router.elf        \
+         build/dhrystone/dhrystone.elf  \
+         build/gameoflife/gameoflife.elf
+### remove all content of virtual disk virt_hdd
+	rm -rf hdd/virt_hdd/*
+### copy content to virtual disk from build, misc and map.bin
+### the boot.elf file is not copied on the virtual disk
+	cp -r build hdd/virt_hdd
+	rm -rf hdd/virt_hdd/build/boot
+	cp -r hdd/misc hdd/virt_hdd
+	cp map.bin  hdd/virt_hdd
+### create temporary partition image (partition_image.dmg)
+	./create_dmg create hdd/virt_hdd partition_image
+### copy standard MBR into virtual disk image (mbr.dmg)
+	cp hdd/mbr.dmg $@ 
+### copy boot.elf into virtual disk image (sector 2)
+	dd if=build/boot/boot.elf of=$@ seek=2
+### copy partition image into virtual disk image (sector 300)
+	dd if=partition_image.dmg of=$@ seek=300 
+### remove partition image
+	rm partition_image.dmg
+
+### mapping compilation
+map.bin: $(MAP_XML)
+	$(MAKE) -C giet_xml
+	giet_xml/xml2bin $< .
+
+### drivers compilation
+build/drivers/dma_driver.o: giet_drivers/dma_driver.c  \
+                            giet_drivers/dma_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/fbf_driver.o: giet_drivers/fbf_driver.c  \
+                            giet_drivers/fbf_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/xcu_driver.o: giet_drivers/xcu_driver.c  \
+                            giet_drivers/xcu_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/icu_driver.o: giet_drivers/icu_driver.c  \
+                            giet_drivers/icu_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/ioc_driver.o: giet_drivers/ioc_driver.c  \
+                            giet_drivers/ioc_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/bdv_driver.o: giet_drivers/bdv_driver.c  \
+                            giet_drivers/bdv_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/sdc_driver.o: giet_drivers/sdc_driver.c  \
+                            giet_drivers/sdc_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/spi_driver.o: giet_drivers/spi_driver.c  \
+                            giet_drivers/spi_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/iob_driver.o: giet_drivers/iob_driver.c  \
+                            giet_drivers/iob_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/mmc_driver.o: giet_drivers/mmc_driver.c  \
+                            giet_drivers/mmc_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/mwr_driver.o: giet_drivers/mwr_driver.c  \
+                            giet_drivers/mwr_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/nic_driver.o: giet_drivers/nic_driver.c  \
+                            giet_drivers/nic_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/tim_driver.o: giet_drivers/tim_driver.c  \
+                            giet_drivers/tim_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/drivers/tty_driver.o: giet_drivers/tty_driver.c  \
+                            giet_drivers/tty_driver.h  \
+                            giet_config.h              \
+                            $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+### fat32 compilation
+build/fat32/fat32.o: giet_fat32/fat32.c \
+                     giet_fat32/fat32.h \
+                     giet_config.h      \
+                     $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+### utils compilation
+build/common/utils.o: giet_common/utils.c \
+                      giet_common/utils.h \
+                      giet_config.h       \
+                      $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+### vmem compilation
+build/common/vmem.o: giet_common/vmem.c \
+                     giet_common/vmem.h \
+                     giet_config.h    \
+                     $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+### boot compilation
+build/boot/boot.elf: $(BOOT_OBJS) 
+	$(LD) -o $@ -T giet_boot/boot.ld $(BOOT_OBJS) 
+	$(DU) -D $@ > $@.txt
+
+build/boot/boot.o: giet_boot/boot.c          \
+                   giet_common/utils.h       \
+                   giet_fat32/fat32.h        \
+                   giet_common/vmem.h        \
+                   giet_drivers/tty_driver.h \
+                   giet_drivers/ioc_driver.h \
+                   giet_config.h             \
+                   $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+### kernel compilation
+build/kernel/kernel.elf: $(KERNEL_OBJS) giet_kernel/kernel.ld 
+	$(LD) -o $@ -T giet_kernel/kernel.ld $(KERNEL_OBJS)
+	$(DU) -D $@ > $@.txt
+
+build/kernel/%.o: giet_kernel/%.c giet_config.h $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/kernel/%.o: giet_kernel/%.s giet_config.h $(MAP_XML)
+	$(CC) $(GIET_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+
+
+
+### libs compilation
+build/libs/stdio.o: giet_libs/stdio.c \
+                    giet_libs/stdio.h \
+                    giet_config.h  
+	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
+
+build/libs/mwmr_channel.o: giet_libs/mwmr_channel.c \
+                           giet_libs/mwmr_channel.h \
+                           giet_config.h
+	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
+
+build/libs/malloc.o: giet_libs/malloc.c         \
+                     giet_libs/malloc.h         \
+                     giet_libs/malloc_private.h \
+                     giet_config.h
+	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
+
+build/libs/barrier.o: giet_libs/barrier.c \
+                      giet_libs/barrier.h \
+                      giet_config.h
+	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
+
+build/libs/stdlib.o: giet_libs/stdlib.c \
+                     giet_libs/stdlib.h \
+                     giet_config.h
+	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
+
+build/libs/string.o: giet_libs/string.c \
+                     giet_libs/string.h \
+                     giet_config.h
+	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
+
+build/libs/spin_lock.o: giet_libs/spin_lock.c \
+                        giet_libs/spin_lock.h \
+                        giet_config.h
+	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
+
+
+
+
+### display compilation
+build/display/display.elf: $(DISPLAY_OBJS) display/display.ld
+	$(LD) -o $@ -T display/display.ld $(DISPLAY_OBJS)
+	$(DU) -D $@ > $@.txt
+
+build/display/main.o: display/main_cma.c
+	$(CC) $(USER_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+### router compilation
+build/router/router.elf: $(ROUTER_OBJS) router/router.ld
+	$(LD) -o $@ -T router/router.ld $(ROUTER_OBJS)
+	$(DU) -D $@ > $@.txt
+
+build/router/main.o: router/main.c
+	$(CC) $(USER_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+### hello compilation
+build/hello/hello.elf: $(HELLO_OBJS) hello/hello.ld
+	$(LD) -o $@ -T hello/hello.ld $(HELLO_OBJS)
+	$(DU) -D $@ > $@.txt
+
+build/hello/main.o: hello/main.c
+	$(CC) $(USER_INCLUDE) $(CFLAGS) -c -o $@ $<
+
+### pgcd compilation
+build/pgcd/pgcd.elf: $(PGCD_OBJS) pgcd/pgcd.ld
+	$(LD) -o $@ -T pgcd/pgcd.ld $(PGCD_OBJS)
+	$(DU) -D $@ > $@.txt
+
+build/pgcd/main.o: pgcd/main.c
+	$(CC) $(USER_INCLUDE) $(CFLAGS) -c -o $@ $<
+
+### gameoflife compilation
+build/gameoflife/gameoflife.elf: $(GAMEOFLIFE_OBJS) gameoflife/gameoflife.ld
+	$(LD) -o $@ -T gameoflife/gameoflife.ld $(GAMEOFLIFE_OBJS)
+	$(DU) -D $@ > $@.txt
+
+build/gameoflife/main.o: gameoflife/main.c
+	$(CC) $(USER_INCLUDE) $(CFLAGS) -O3 -c -o $@ $<
+
+### dhrystone compilation
+build/dhrystone/dhrystone.elf: $(DHRYSTONE_OBJS) dhrystone/dhrystone.ld
+	$(LD) -o $@ -T dhrystone/dhrystone.ld $(DHRYSTONE_OBJS)
+	$(DU) -D $@ > $@.txt
+
+build/dhrystone/dhry_1.o: dhrystone/dhry_1.c
+	$(CC) $(USER_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+build/dhrystone/dhry_2.o: dhrystone/dhry_2.c
+	$(CC) $(USER_INCLUDE) $(CFLAGS)  -c -o $@ $<
+
+### sort compilation
+build/sort/sort.elf: $(SORT_OBJS) sort/sort.ld 
+	$(LD) -o $@ -T sort/sort.ld $(SORT_OBJS)
+	$(DU) -D $@ > $@.txt
+
+build/sort/main.o: sort/main.c
+	$(CC) $(USER_INCLUDE) $(CFLAGS) -c -o $@ $<
+
+### clean 
+clean:
+	rm -f *.o *.elf *.bin *.txt core  giet_vsegs.ld hard_config.h map.bin*~
+	$(MAKE) -s clean -C giet_xml
+	rm -rf build/boot/*
+	rm -rf build/fat32/*
+	rm -rf build/common/*
+	rm -rf build/drivers/*
+	rm -rf build/kernel/*
+	rm -rf build/reset/*
+	rm -rf build/libs/*
+	rm -rf build/pgcd/*
+	rm -rf build/hello/*
+	rm -rf build/display/*
+	rm -rf build/router/*
+	rm -rf build/gameoflife/*
+	rm -rf build/dhrystone/*
+	rm -rf build/sort/*
+	rm -rf build/map.bin
+	rm -rf hdd/virt_hdd/*
+	rm -rf hdd/virt_hdd.dmg
Index: /branch/giet_vm_ioc_drivers/create_dmg
===================================================================
--- /branch/giet_vm_ioc_drivers/create_dmg	(revision 283)
+++ /branch/giet_vm_ioc_drivers/create_dmg	(revision 283)
@@ -0,0 +1,162 @@
+#!/bin/bash
+# Author: Cesar FUGUET
+# Date  : Novembre 2013
+
+clusters=65536
+sector_size=512
+sectors_per_cluster=8
+reserved_sectors=32
+
+# FAT32 SPEC: The first two clusters are not present in the data region but
+# they are used in the computation of the FAT sectors
+data_region_clusters=$clusters-2
+
+let "data_sectors = data_region_clusters * sectors_per_cluster"
+let "fat_sectors  = (clusters * 4) / 512"
+
+# The disk image contains:
+#   - MBR sector : this sector is removed by this script as it will be copied
+#                  after)
+#   - Reserved region sectors (usually 32)
+#   - FAT region sectors
+#   - DATA region sectors
+let "sectors      = data_sectors + fat_sectors + reserved_sectors + 1" 
+
+platform=`uname`
+echo "Detected platform: $platform"
+
+if [[ $platform == "Darwin" ]]; then
+	case $1 in
+		create )
+			# Create disk image
+			# -fs        <fs>   : use filesystem <fs>
+			# -volname   <name> : use volume name <name>
+			# -srcfolder <src>  : copy every file in <src> into image
+			# -format    <fmt>  : format of image. UDRW (UDIF read/write image)
+			# -sectors   <sect> : size of image in 512-byte sectors
+			# -ov				: overwrite existing image file
+			# -fargs	 <args> : additional args to pass to newfs program 
+			#			     -F : FAT type (FAT32)
+			#				 -c : sector per cluster
+			#				 -n : number of FAT
+
+			if [[ -z $2 ]]; then
+				echo "Create action need second argument: <srcdir_path>"
+				exit 1;
+			fi;
+
+			if [[ -z $3 ]]; then
+				echo "Create action need third argument: <disk_image>"
+				exit 1;
+			fi;
+
+			# RAW DISK IMAGE READ-ONLY
+			# The not used space is not considered (smaller disk image)
+			# format="UDRO"
+
+			# RAW DISK IMAGE READ-WRITE
+			# None compression is made
+			format="UDRW" 
+
+			echo "Creating partition file $3 from $2 directory"
+			hdiutil create \
+				-fs MS-DOS \
+				-volname virtualdisk \
+				-srcfolder $2 \
+				-sectors $sectors \
+				-ov \
+				-fsargs "-F32 -c$sectors_per_cluster -n1 -r$reserved_sectors" \
+				-format $format \
+				$3; 
+#				-verbose \
+
+			echo "Removing first sector of diskimage"
+
+			if [[ -e "/tmp" ]]; then
+				if [[ -e "/tmp/diskimage" ]]; then
+					echo "Warning /tmp/diskimage exists already. Rename it or"
+					echo "remove it before executing this script"
+					exit
+				fi;
+
+				dd if=$3.dmg of=/tmp/diskimage iseek=1 oseek=0
+				mv /tmp/diskimage $3.dmg
+			fi;;
+
+		attach )
+			# Attach created disk image to the system and mount it
+			hdiutil attach $2;;
+
+		detach )
+			# Detach attached device. Must pass as parameter the /dev/<device>
+			hdiutil detach $2;;
+
+		info )
+			hdiutil imageinfo $2;;
+
+		* )
+			echo "Pass the command as the first parameter: "
+			echo "  - create: create disk image"
+			echo "            First parameter after create action is the path"
+		    echo "            of the directory to copy in the created "
+			echo "            partition"
+			echo "  - attach: attach created disk image to the system and "
+			echo "            mount it (arg: path to disk_image)"
+			echo "  - detach: detach specified device "
+			echo "            (arg: path to /dev/<device>)"
+			echo "  - info  : print information about created disk image"
+			echo "            (arg: path to disk_image)"
+			echo ""
+			echo "EXAMPLES:"
+			echo " ./create_diskimage.sh create /path/to/source_dir disk_image"
+			echo " ./create_diskimage.sh attach /path/to/disk_image.dmg"
+			echo " ./create_diskimage.sh detach /dev/disk5"
+			echo " ./create_diskimage.sh info   /path/to/disk_image.dmg"
+	esac;
+
+elif [[ $platform == "Linux" ]]; then
+	case $1 in
+		create )
+			if [[ -z $2 ]]; then
+				echo "Create action need second argument: <srcdir_path>"
+				exit 1;
+			fi;
+
+			if [[ -z $3 ]]; then
+				echo "Create action need third argument: <disk_image>"
+				exit 1;
+			fi;
+
+			echo "Creating partition file: $3"
+
+			let "sectors = (sectors - 1) / 2" 
+		    mkfs.vfat \
+				-C \
+				-F32 \
+				-f 1 \
+				-R $reserved_sectors \
+				-S $sector_size \
+				-s $sectors_per_cluster \
+				-v \
+				$3.dmg $sectors
+
+			if [[ -e $2 ]]; then
+				echo "Copying files from $2 into partition"
+				mcopy -s -i $3.dmg $2/* :://
+			fi;;
+
+		* )
+			echo "Pass the command as the first parameter: "
+			echo "  - create: create disk image"
+			echo "            First parameter after create action is the path"
+		    echo "            of the directory to copy in the created "
+			echo "            partition"
+			echo ""
+			echo "EXAMPLES:"
+			echo " ./create_diskimage.sh create /path/to/source_dir disk_image"
+	esac;
+
+else
+	echo "Your platform is not supported: $platform"
+fi;
+
Index: /branch/giet_vm_ioc_drivers/dhrystone/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/dhrystone/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/dhrystone/Makefile	(revision 283)
@@ -0,0 +1,24 @@
+APP_NAME=dhrystone
+
+USE+= stdio.o
+#USE+= mwmr_channel.o
+
+USES=$(patsubst %,$(BUILD_PATH)/$(LIB_NAME)/%,$(USE))
+
+OBJS= dhry_1.o dhry_2.o
+
+all: $(APP_NAME).elf
+
+BIN_NAME_PATH=$(BUILD_PATH)$(APP_NAME).elf
+
+$(APP_NAME).elf: $(OBJS) $(APP_NAME).ld
+	$(LD) -o $(BIN_NAME_PATH) -T $(APP_NAME).ld $(OBJS) $(USES)
+	$(DU) -D $(BIN_NAME_PATH) > $@.txt
+
+%.o: %.c 
+	$(CC)  $(INCLUDE) $(CFLAGS) $($*.o_CFLAGS) -c -o  $@ $<
+	$(DU) -D  $@ >  $@.txt
+
+clean:
+	rm -f *.o *.elf *.txt core *~ 2>$(TRASH)
+	rm $(BIN_NAME_PATH) 2>$(TRASH)
Index: /branch/giet_vm_ioc_drivers/dhrystone/dhry.h
===================================================================
--- /branch/giet_vm_ioc_drivers/dhrystone/dhry.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/dhrystone/dhry.h	(revision 283)
@@ -0,0 +1,448 @@
+/////////////////////////////////////////////////////////////////////////////
+// File     : dhry.h 
+// Date     : 22/05/2013
+// Author   : Alexandre JOANNOU
+//
+// Port of dhrystone benchmark on the giet_vm operating system
+//
+// Defines:     The following "Defines" are possible:
+//              -DNB_RUN=nnn
+//                  Specifies the number of runs (default = 10000000)
+/////////////////////////////////////////////////////////////////////////////
+
+/*
+ ****************************************************************************
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry.h (part 1 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *                      Siemens AG, E STE 35
+ *                      Postfach 3240
+ *                      8520 Erlangen
+ *                      Germany (West)
+ *                              Phone:  [xxx-49]-9131-7-20330
+ *                                      (8-17 Central European Time)
+ *                              Usenet: ..!mcvax!unido!estevax!weicker
+ *
+ *              Original Version (in Ada) published in
+ *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ *              pp. 1013 - 1030, together with the statistics
+ *              on which the distribution of statements etc. is based.
+ *
+ *              In this C version, the following C library functions are used:
+ *              - strcpy, strcmp (inside the measurement loop)
+ *              - printf (outside the measurement loop)
+ *              In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ *              are used for execution time measurement. For measurements
+ *              on other systems, these calls have to be changed.
+ *
+ *  Collection of Results:
+ *              Reinhold Weicker (address see above) and
+ *              
+ *              Rick Richardson
+ *              PC Research. Inc.
+ *              94 Apple Orchard Drive
+ *              Tinton Falls, NJ 07724
+ *                      Phone:  (201) 389-8963 (9-17 EST)               
+ *                      Usenet: ...!uunet!pcrat!rick
+ *
+ *      Please send results to Rick Richardson and/or Reinhold Weicker.
+ *      Complete information should be given on hardware and software used.
+ *      Hardware information includes: Machine type, CPU, type and size
+ *      of caches; for microprocessors: clock frequency, memory speed
+ *      (number of wait states).
+ *      Software information includes: Compiler (and runtime library)
+ *      manufacturer and version, compilation switches, OS version.
+ *      The Operating System version may give an indication about the
+ *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ *      The complete output generated by the program should be mailed
+ *      such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ *  History:    This version C/2.1 has been made for two reasons:
+ *
+ *              1) There is an obvious need for a common C version of
+ *              Dhrystone, since C is at present the most popular system
+ *              programming language for the class of processors
+ *              (microcomputers, minicomputers) where Dhrystone is used most.
+ *              There should be, as far as possible, only one C version of
+ *              Dhrystone such that results can be compared without
+ *              restrictions. In the past, the C versions distributed
+ *              by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ *              had small (though not significant) differences.
+ *
+ *              2) As far as it is possible without changes to the Dhrystone
+ *              statistics, optimizing compilers should be prevented from
+ *              removing significant statements.
+ *
+ *              This C version has been developed in cooperation with
+ *              Rick Richardson (Tinton Falls, NJ), it incorporates many
+ *              ideas from the "Version 1.1" distributed previously by
+ *              him over the UNIX network Usenet.
+ *              I also thank Chaim Benedelac (National Semiconductor),
+ *              David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ *              for their help with comments on earlier versions of the
+ *              benchmark.
+ *
+ *  Changes:    In the initialization part, this version follows mostly
+ *              Rick Richardson's version distributed via Usenet, not the
+ *              version distributed earlier via floppy disk by Reinhold Weicker.
+ *              As a concession to older compilers, names have been made
+ *              unique within the first 8 characters.
+ *              Inside the measurement loop, this version follows the
+ *              version previously distributed by Reinhold Weicker.
+ *
+ *              At several places in the benchmark, code has been added,
+ *              but within the measurement loop only in branches that 
+ *              are not executed. The intention is that optimizing compilers
+ *              should be prevented from moving code out of the measurement
+ *              loop, or from removing code altogether. Since the statements
+ *              that are executed within the measurement loop have NOT been
+ *              changed, the numbers defining the "Dhrystone distribution"
+ *              (distribution of statements, operand types and locality)
+ *              still hold. Except for sophisticated optimizing compilers,
+ *              execution times for this version should be the same as
+ *              for previous versions.
+ *              
+ *              Since it has proven difficult to subtract the time for the
+ *              measurement loop overhead in a correct way, the loop check
+ *              has been made a part of the benchmark. This does have
+ *              an impact - though a very minor one - on the distribution
+ *              statistics which have been updated for this version.
+ *
+ *              All changes within the measurement loop are described
+ *              and discussed in the companion paper "Rationale for
+ *              Dhrystone version 2".
+ *
+ *              Because of the self-imposed limitation that the order and
+ *              distribution of the executed statements should not be
+ *              changed, there are still cases where optimizing compilers
+ *              may not generate code for some statements. To a certain
+ *              degree, this is unavoidable for small synthetic benchmarks.
+ *              Users of the benchmark are advised to check code listings
+ *              whether code is generated for all statements of Dhrystone.
+ *
+ *              Version 2.1 is identical to version 2.0 distributed via
+ *              the UNIX network Usenet in March 1988 except that it corrects
+ *              some minor deficiencies that were found by users of version 2.0.
+ *              The only change within the measurement loop is that a
+ *              non-executed "else" part was added to the "if" statement in
+ *              Func_3, and a non-executed "else" part removed from Proc_3.
+ *
+ ***************************************************************************
+ *
+ * Defines:     The following "Defines" are possible:
+ *              -DREG=register          (default: Not defined)
+ *                      As an approximation to what an average C programmer
+ *                      might do, the "register" storage class is applied
+ *                      (if enabled by -DREG=register)
+ *                      - for local variables, if they are used (dynamically)
+ *                        five or more times
+ *                      - for parameters if they are used (dynamically)
+ *                        six or more times
+ *                      Note that an optimal "register" strategy is
+ *                      compiler-dependent, and that "register" declarations
+ *                      do not necessarily lead to faster execution.
+ *              -DNOSTRUCTASSIGN        (default: Not defined)
+ *                      Define if the C compiler does not support
+ *                      assignment of structures.
+ *              -DNOENUMS               (default: Not defined)
+ *                      Define if the C compiler does not support
+ *                      enumeration types.
+ *              -DTIMES                 (default)
+ *              -DTIME
+ *                      The "times" function of UNIX (returning process times)
+ *                      or the "time" function (returning wallclock time)
+ *                      is used for measurement. 
+ *                      For single user machines, "time ()" is adequate. For
+ *                      multi-user machines where you cannot get single-user
+ *                      access, use the "times ()" function. If you have
+ *                      neither, use a stopwatch in the dead of night.
+ *                      "printf"s are provided marking the points "Start Timer"
+ *                      and "Stop Timer". DO NOT use the UNIX "time(1)"
+ *                      command, as this will measure the total time to
+ *                      run this program, which will (erroneously) include
+ *                      the time to allocate storage (malloc) and to perform
+ *                      the initialization.
+ *              -DHZ=nnn
+ *                      In Berkeley UNIX, the function "times" returns process
+ *                      time in 1/HZ seconds, with HZ = 60 for most systems.
+ *                      CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+ *                      A VALUE.
+ *
+ ***************************************************************************
+ *
+ *  Compilation model and measurement (IMPORTANT):
+ *
+ *  This C version of Dhrystone consists of three files:
+ *  - dhry.h (this file, containing global definitions and comments)
+ *  - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ *  - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ *  The following "ground rules" apply for measurements:
+ *  - Separate compilation
+ *  - No procedure merging
+ *  - Otherwise, compiler optimizations are allowed but should be indicated
+ *  - Default results are those without register declarations
+ *  See the companion paper "Rationale for Dhrystone Version 2" for a more
+ *  detailed discussion of these ground rules.
+ *
+ *  For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ *  models ("small", "medium", "large" etc.) should be given if possible,
+ *  together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ *
+ *  Dhrystone (C version) statistics:
+ *
+ *  [Comment from the first distribution, updated for version 2.
+ *   Note that because of language differences, the numbers are slightly
+ *   different from the Ada version.]
+ *
+ *  The following program contains statements of a high level programming
+ *  language (here: C) in a distribution considered representative:           
+ *
+ *    assignments                  52 (51.0 %)
+ *    control statements           33 (32.4 %)
+ *    procedure, function calls    17 (16.7 %)
+ *
+ *  103 statements are dynamically executed. The program is balanced with
+ *  respect to the three aspects:                                             
+ *
+ *    - statement type
+ *    - operand type
+ *    - operand locality
+ *         operand global, local, parameter, or constant.                     
+ *
+ *  The combination of these three aspects is balanced only approximately.    
+ *
+ *  1. Statement Type:                                                        
+ *  -----------------             number
+ *
+ *     V1 = V2                     9
+ *       (incl. V1 = F(..)
+ *     V = Constant               12
+ *     Assignment,                 7
+ *       with array element
+ *     Assignment,                 6
+ *       with record component
+ *                                --
+ *                                34       34
+ *
+ *     X = Y +|-|"&&"|"|" Z        5
+ *     X = Y +|-|"==" Constant     6
+ *     X = X +|- 1                 3
+ *     X = Y *|/ Z                 2
+ *     X = Expression,             1
+ *           two operators
+ *     X = Expression,             1
+ *           three operators
+ *                                --
+ *                                18       18
+ *
+ *     if ....                    14
+ *       with "else"      7
+ *       without "else"   7
+ *           executed        3
+ *           not executed    4
+ *     for ...                     7  |  counted every time
+ *     while ...                   4  |  the loop condition
+ *     do ... while                1  |  is evaluated
+ *     switch ...                  1
+ *     break                       1
+ *     declaration with            1
+ *       initialization
+ *                                --
+ *                                34       34
+ *
+ *     P (...)  procedure call    11
+ *       user procedure      10
+ *       library procedure    1
+ *     X = F (...)
+ *             function  call      6
+ *       user function        5                                         
+ *       library function     1                                               
+ *                                --                                          
+ *                                17       17
+ *                                        ---
+ *                                        103
+ *
+ *    The average number of parameters in procedure or function calls
+ *    is 1.82 (not counting the function values aX *
+ *
+ *  2. Operators
+ *  ------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *    Arithmetic             32          50.8                                 
+ *
+ *       +                     21          33.3                              
+ *       -                      7          11.1                              
+ *       *                      3           4.8
+ *       / (int div)            1           1.6
+ *
+ *    Comparison             27           42.8
+ *
+ *       ==                     9           14.3
+ *       /=                     4            6.3
+ *       >                      1            1.6
+ *       <                      3            4.8
+ *       >=                     1            1.6
+ *       <=                     9           14.3
+ *
+ *    Logic                   4            6.3
+ *
+ *       && (AND-THEN)          1            1.6
+ *       |  (OR)                1            1.6
+ *       !  (NOT)               2            3.2
+ * 
+ *                           --          -----
+ *                           63          100.1
+ *
+ *
+ *  3. Operand Type (counted once per operand reference):
+ *  ---------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *     Integer               175        72.3 %
+ *     Character              45        18.6 %
+ *     Pointer                12         5.0 %
+ *     String30                6         2.5 %
+ *     Array                   2         0.8 %
+ *     Record                  2         0.8 %
+ *                           ---       -------
+ *                           242       100.0 %
+ *
+ *  When there is an access path leading to the final operand (e.g. a record
+ *  component), only the final data type on the access path is counted.       
+ *
+ *
+ *  4. Operand Locality:                                                      
+ *  -------------------
+ *                                number    approximate
+ *                                          percentage
+ *
+ *     local variable              114        47.1 %
+ *     global variable              22         9.1 %
+ *     parameter                    45        18.6 %
+ *     value                        23         9.5 %
+ *     reference                    22         9.1 %
+ *     function result               6         2.5 %
+ *     constant                     55        22.7 %
+ *                                 ---       -------
+ *                                 242       100.0 %
+ *
+ *
+ *  The program does not compute anything meaningful, but it is syntactically
+ *  and semantically correct. All variables have a value assigned to them
+ *  before they are used as a source operand.
+ *
+ *  There has been no explicit effort to account for the effects of a
+ *  cache, or to balance the use of long or short displacements for code or
+ *  data.
+ *
+ ***************************************************************************
+ */
+
+#ifndef _DHRY_H_
+#define _DHRY_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+typedef int     One_Thirty;
+typedef int     One_Fifty;
+typedef char    Capital_Letter;
+typedef int     Boolean;
+typedef char    Str_30 [31];
+typedef int     Arr_1_Dim [50];
+typedef int     Arr_2_Dim [50] [50];
+
+#define printf(...) giet_tty_printf(__VA_ARGS__)
+
+#define Mic_secs_Per_Second     1000000.0
+
+#ifndef NB_RUN
+#define NB_RUN 10
+#endif
+
+#ifdef  NOSTRUCTASSIGN
+void memcpy (register char *d, register char *s, register int l)
+{
+        while (l--) *d++ = *s++;
+}
+#define structassign(d, s)      memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s)      d = s
+#endif
+
+#ifdef  NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+  typedef int   Enumeration;
+#else
+  typedef       enum    {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+                Enumeration;
+#endif
+
+#define Null ((void*)0)
+                /* Value of a Null pointer */
+#define true  1
+#define false 0
+
+typedef struct record 
+{
+    struct record *Ptr_Comp;
+    Enumeration    Discr;
+    union {
+        struct {
+            Enumeration Enum_Comp;
+            int         Int_Comp;
+            char        Str_Comp [31];
+        } var_1;
+        struct {
+            Enumeration E_Comp_2;
+            char        Str_2_Comp [31];
+        } var_2;
+        struct {
+            char        Ch_1_Comp;
+            char        Ch_2_Comp;
+        } var_3;
+    } variant;
+} Rec_Type, *Rec_Pointer;
+
+#ifdef REG
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
+#else
+void Proc_1 (Rec_Pointer Ptr_Val_Par);
+#endif
+void Proc_2 (One_Fifty *Int_Par_Ref);
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
+void Proc_4 ();
+void Proc_5 ();
+void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par);
+void Proc_7 (One_Fifty Int_1_Par_Val, One_Fifty Int_2_Par_Val, One_Fifty *Int_Par_Ref);
+void Proc_8 (Arr_1_Dim Arr_1_Par_Ref, Arr_2_Dim Arr_2_Par_Ref, int Int_1_Par_Val, int Int_2_Par_Val);
+
+Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val);
+Boolean Func_2 (Str_30 Str_1_Par_Ref, Str_30 Str_2_Par_Ref);
+Boolean Func_3 (Enumeration Enum_Par_Val);
+
+#endif
Index: /branch/giet_vm_ioc_drivers/dhrystone/dhry_1.c
===================================================================
--- /branch/giet_vm_ioc_drivers/dhrystone/dhry_1.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/dhrystone/dhry_1.c	(revision 283)
@@ -0,0 +1,353 @@
+/////////////////////////////////////////////////////////////////////////////
+// File     : dhry_1.c 
+// Date     : 22/05/2013
+// Author   : Alexandre JOANNOU
+//
+// Port of dhrystone benchmark on the giet_vm operating system
+//
+/////////////////////////////////////////////////////////////////////////////
+/*
+ ****************************************************************************
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry_1.c (part 2 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *
+ ****************************************************************************
+ */
+
+#include "dhry.h"
+
+#ifndef REG
+        Boolean Reg = false;
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#else
+        Boolean Reg = true;
+#endif
+
+/* Global Variables: */
+
+Rec_Pointer     Ptr_Glob,
+                Next_Ptr_Glob;
+int             Int_Glob;
+Boolean         Bool_Glob;
+char            Ch_1_Glob,
+                Ch_2_Glob;
+int             Arr_1_Glob [50];
+int             Arr_2_Glob [50] [50];
+
+/* variables for time measurement: */
+#define         Too_Small_Time 50000
+long            Begin_Time,
+                End_Time,
+                User_Time;
+float           Cycles;
+
+/* end of variables for time measurement */
+
+void Proc_1 ( REG Rec_Pointer Ptr_Val_Par)
+/* executed once */
+{
+  REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;  
+                                        /* == Ptr_Glob_Next */
+  /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp,    */
+  /* corresponds to "rename" in Ada, "with" in Pascal           */
+  
+  structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); 
+  Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+  Next_Record->variant.var_1.Int_Comp 
+        = Ptr_Val_Par->variant.var_1.Int_Comp;
+  Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+  Proc_3 (&Next_Record->Ptr_Comp);
+    /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp 
+                        == Ptr_Glob->Ptr_Comp */
+  if (Next_Record->Discr == Ident_1)
+    /* then, executed */
+  {
+    Next_Record->variant.var_1.Int_Comp = 6;
+    Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, 
+           &Next_Record->variant.var_1.Enum_Comp);
+    Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+    Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, 
+           &Next_Record->variant.var_1.Int_Comp);
+  }
+  else /* not executed */
+    structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+} /* Proc_1 */
+
+
+void Proc_2 (One_Fifty   *Int_Par_Ref)
+/******************/
+    /* executed once */
+    /* *Int_Par_Ref == 1, becomes 4 */
+
+{
+  One_Fifty  Int_Loc;  
+  Enumeration   Enum_Loc;
+
+  Int_Loc = *Int_Par_Ref + 10;
+  do /* executed once */
+    if (Ch_1_Glob == 'A')
+      /* then, executed */
+    {
+      Int_Loc -= 1;
+      *Int_Par_Ref = Int_Loc - Int_Glob;
+      Enum_Loc = Ident_1;
+    } /* if */
+  while (Enum_Loc != Ident_1); /* true */
+} /* Proc_2 */
+
+
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
+/******************/
+    /* executed once */
+    /* Ptr_Ref_Par becomes Ptr_Glob */
+{
+  if (Ptr_Glob != Null)
+    /* then, executed */
+    *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+  Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+void Proc_4 () /* without parameters */
+/*******/
+    /* executed once */
+{
+  Boolean Bool_Loc;
+
+  Bool_Loc = Ch_1_Glob == 'A';
+  Bool_Glob = Bool_Loc | Bool_Glob;
+  Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+
+void Proc_5 () /* without parameters */
+/*******/
+    /* executed once */
+{
+  Ch_1_Glob = 'A';
+  Bool_Glob = false;
+} /* Proc_5 */
+
+        /* Procedure for the assignment of structures,          */
+        /* if the C compiler doesn't support this feature       */
+#ifdef  NOSTRUCTASSIGN
+memcpy (d, s, l)
+register char   *d;
+register char   *s;
+register int    l;
+{
+        while (l--) *d++ = *s++;
+}
+#endif
+
+__attribute__ ((constructor)) int main ()
+/*****/
+  /* main program, corresponds to procedures        */
+  /* Main and Proc_0 in the Ada version             */
+{
+        One_Fifty       Int_1_Loc;
+  REG   One_Fifty       Int_2_Loc;
+        One_Fifty       Int_3_Loc;
+  REG   char            Ch_Index;
+        Enumeration     Enum_Loc;
+        Str_30          Str_1_Loc;
+        Str_30          Str_2_Loc;
+  REG   int             Run_Index;
+  REG   int             Number_Of_Runs;
+
+  /* Initializations */
+
+  Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+  Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+
+  Ptr_Glob->Ptr_Comp                    = Next_Ptr_Glob;
+  Ptr_Glob->Discr                       = Ident_1;
+  Ptr_Glob->variant.var_1.Enum_Comp     = Ident_3;
+  Ptr_Glob->variant.var_1.Int_Comp      = 40;
+  strcpy (Ptr_Glob->variant.var_1.Str_Comp, 
+          "DHRYSTONE PROGRAM, SOME STRING");
+  strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+  Arr_2_Glob [8][7] = 10;
+        /* Was missing in published program. Without this statement,    */
+        /* Arr_2_Glob [8][7] would have an undefined value.             */
+        /* Warning: With 16-Bit processors and Number_Of_Runs > 32000,  */
+        /* overflow may occur for this array element.                   */
+
+  printf ("\n");
+  printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+  printf ("\n");
+  if (Reg)
+  {
+    printf ("Program compiled with 'register' attribute\n");
+    printf ("\n");
+  }
+  else
+  {
+    printf ("Program compiled without 'register' attribute\n");
+    printf ("\n");
+  }
+  printf ("Please give the number of runs through the benchmark: ");
+  {
+    /*
+    int n;
+    scanf ("%d", &n);
+    */
+    int n = NB_RUN;
+    Number_Of_Runs = n;
+  }
+  printf ("\n");
+
+  printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+
+  /***************/
+  /* Start timer */
+  /***************/
+ 
+  Begin_Time = giet_proctime();
+
+  for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
+  {
+
+    Proc_5();
+    Proc_4();
+      /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+    Int_1_Loc = 2;
+    Int_2_Loc = 3;
+    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+    Enum_Loc = Ident_2;
+    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+      /* Bool_Glob == 1 */
+    while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */
+    {
+      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+        /* Int_3_Loc == 7 */
+      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+        /* Int_3_Loc == 7 */
+      Int_1_Loc += 1;
+    } /* while */
+      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+      /* Int_Glob == 5 */
+    Proc_1 (Ptr_Glob);
+    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+                             /* loop body executed twice */
+    {
+      if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+          /* then, not executed */
+        {
+        Proc_6 (Ident_1, &Enum_Loc);
+        strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+        Int_2_Loc = Run_Index;
+        Int_Glob = Run_Index;
+        }
+    }
+      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+    Int_2_Loc = Int_2_Loc * Int_1_Loc;
+    Int_1_Loc = Int_2_Loc / Int_3_Loc;
+    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+      /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+    Proc_2 (&Int_1_Loc);
+      /* Int_1_Loc == 5 */
+
+  } /* loop "for Run_Index" */
+
+  /**************/
+  /* Stop timer */
+  /**************/
+  
+  End_Time = giet_proctime();
+
+  printf ("Execution ends\n");
+  printf ("\n");
+  printf ("Final values of the variables used in the benchmark:\n");
+  printf ("\n");
+  printf ("Int_Glob:            %d\n", Int_Glob);
+  printf ("        should be:   %d\n", 5);
+  printf ("Bool_Glob:           %d\n", Bool_Glob);
+  printf ("        should be:   %d\n", 1);
+  printf ("Ch_1_Glob:           %c\n", Ch_1_Glob);
+  printf ("        should be:   %c\n", 'A');
+  printf ("Ch_2_Glob:           %c\n", Ch_2_Glob);
+  printf ("        should be:   %c\n", 'B');
+  printf ("Arr_1_Glob[8]:       %d\n", Arr_1_Glob[8]);
+  printf ("        should be:   %d\n", 7);
+  printf ("Arr_2_Glob[8][7]:    %d\n", Arr_2_Glob[8][7]);
+  printf ("        should be:   Number_Of_Runs + 10\n");
+  printf ("Ptr_Glob->\n");
+  printf ("  Ptr_Comp:          %d\n", (int) Ptr_Glob->Ptr_Comp);
+  printf ("        should be:   (implementation-dependent)\n");
+  printf ("  Discr:             %d\n", Ptr_Glob->Discr);
+  printf ("        should be:   %d\n", 0);
+  printf ("  Enum_Comp:         %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+  printf ("        should be:   %d\n", 2);
+  printf ("  Int_Comp:          %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+  printf ("        should be:   %d\n", 17);
+  printf ("  Str_Comp:          %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+  printf ("Next_Ptr_Glob->\n");
+  printf ("  Ptr_Comp:          %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+  printf ("        should be:   (implementation-dependent), same as above\n");
+  printf ("  Discr:             %d\n", Next_Ptr_Glob->Discr);
+  printf ("        should be:   %d\n", 0);
+  printf ("  Enum_Comp:         %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+  printf ("        should be:   %d\n", 1);
+  printf ("  Int_Comp:          %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+  printf ("        should be:   %d\n", 18);
+  printf ("  Str_Comp:          %s\n",
+                                Next_Ptr_Glob->variant.var_1.Str_Comp);
+  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+  printf ("Int_1_Loc:           %d\n", Int_1_Loc);
+  printf ("        should be:   %d\n", 5);
+  printf ("Int_2_Loc:           %d\n", Int_2_Loc);
+  printf ("        should be:   %d\n", 13);
+  printf ("Int_3_Loc:           %d\n", Int_3_Loc);
+  printf ("        should be:   %d\n", 7);
+  printf ("Enum_Loc:            %d\n", Enum_Loc);
+  printf ("        should be:   %d\n", 1);
+  printf ("Str_1_Loc:           %s\n", Str_1_Loc);
+  printf ("        should be:   DHRYSTONE PROGRAM, 1'ST STRING\n");
+  printf ("Str_2_Loc:           %s\n", Str_2_Loc);
+  printf ("        should be:   DHRYSTONE PROGRAM, 2'ND STRING\n");
+  printf ("\n");
+
+  User_Time = End_Time - Begin_Time;
+
+  printf ("Start cycle : %d\nEnd cycle : %d\n",Begin_Time,End_Time);
+  printf ("Total work cycles : %d\nNB run : %d\nCycles per run : %d\n",User_Time,Number_Of_Runs,User_Time/Number_Of_Runs);
+
+/*
+  if (User_Time < Too_Small_Time)
+  {
+    printf ("Measured time too small to obtain meaningful results\n");
+    printf ("Please increase number of runs\n");
+    printf ("\n");
+  }
+  else
+  {
+    Cycles = (float) User_Time / (float) Number_Of_Runs;
+    printf ("Cycles for one run through Dhrystone: ");
+    printf ("%6.1f \n", Cycles);
+    printf ("\n");
+  }
+*/
+
+  free(Next_Ptr_Glob);
+  free(Ptr_Glob);
+
+  giet_exit();
+
+  return 0;
+}
+
Index: /branch/giet_vm_ioc_drivers/dhrystone/dhry_2.c
===================================================================
--- /branch/giet_vm_ioc_drivers/dhrystone/dhry_2.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/dhrystone/dhry_2.c	(revision 283)
@@ -0,0 +1,192 @@
+/*
+ ****************************************************************************
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry_2.c (part 3 of 3)
+ *
+ *  Date:       May 25, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *
+ ****************************************************************************
+ */
+
+#include "dhry.h"
+
+#ifndef REG
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#endif
+
+extern  int     Int_Glob;
+extern  char    Ch_1_Glob;
+
+
+void Proc_6 (Enum_Val_Par, Enum_Ref_Par)
+/*********************************/
+    /* executed once */
+    /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+
+Enumeration  Enum_Val_Par;
+Enumeration *Enum_Ref_Par;
+{
+  *Enum_Ref_Par = Enum_Val_Par;
+  if (! Func_3 (Enum_Val_Par))
+    /* then, not executed */
+    *Enum_Ref_Par = Ident_4;
+  switch (Enum_Val_Par)
+  {
+    case Ident_1: 
+      *Enum_Ref_Par = Ident_1;
+      break;
+    case Ident_2: 
+      if (Int_Glob > 100)
+        /* then */
+      *Enum_Ref_Par = Ident_1;
+      else *Enum_Ref_Par = Ident_4;
+      break;
+    case Ident_3: /* executed */
+      *Enum_Ref_Par = Ident_2;
+      break;
+    case Ident_4: break;
+    case Ident_5: 
+      *Enum_Ref_Par = Ident_3;
+      break;
+  } /* switch */
+} /* Proc_6 */
+
+
+void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+/**********************************************/
+    /* executed three times                                      */ 
+    /* first call:      Int_1_Par_Val == 2, Int_2_Par_Val == 3,  */
+    /*                  Int_Par_Ref becomes 7                    */
+    /* second call:     Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+    /*                  Int_Par_Ref becomes 17                   */
+    /* third call:      Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+    /*                  Int_Par_Ref becomes 18                   */
+One_Fifty       Int_1_Par_Val;
+One_Fifty       Int_2_Par_Val;
+One_Fifty      *Int_Par_Ref;
+{
+  One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 2;
+  *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+/*********************************************************************/
+    /* executed once      */
+    /* Int_Par_Val_1 == 3 */
+    /* Int_Par_Val_2 == 7 */
+Arr_1_Dim       Arr_1_Par_Ref;
+Arr_2_Dim       Arr_2_Par_Ref;
+int             Int_1_Par_Val;
+int             Int_2_Par_Val;
+{
+  REG One_Fifty Int_Index;
+  REG One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 5;
+  Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+  Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+  Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+  for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+    Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+  Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+  Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+  Int_Glob = 5;
+} /* Proc_8 */
+
+
+Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
+/*************************************************/
+    /* executed three times                                         */
+    /* first call:      Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R'    */
+    /* second call:     Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C'    */
+    /* third call:      Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C'    */
+
+Capital_Letter   Ch_1_Par_Val;
+Capital_Letter   Ch_2_Par_Val;
+{
+  Capital_Letter        Ch_1_Loc;
+  Capital_Letter        Ch_2_Loc;
+
+  Ch_1_Loc = Ch_1_Par_Val;
+  Ch_2_Loc = Ch_1_Loc;
+  if (Ch_2_Loc != Ch_2_Par_Val)
+    /* then, executed */
+    return (Ident_1);
+  else  /* not executed */
+  {
+    Ch_1_Glob = Ch_1_Loc;
+    return (Ident_2);
+   }
+} /* Func_1 */
+
+
+Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
+/*************************************************/
+    /* executed once */
+    /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+    /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+Str_30  Str_1_Par_Ref;
+Str_30  Str_2_Par_Ref;
+{
+  REG One_Thirty        Int_Loc;
+      Capital_Letter    Ch_Loc;
+
+  Int_Loc = 2;
+  while (Int_Loc <= 2) /* loop body executed once */
+    if (Func_1 (Str_1_Par_Ref[Int_Loc],
+                Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+      /* then, executed */
+    {
+      Ch_Loc = 'A';
+      Int_Loc += 1;
+    } /* if, while */
+  if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+    /* then, not executed */
+    Int_Loc = 7;
+  if (Ch_Loc == 'R')
+    /* then, not executed */
+    return (true);
+  else /* executed */
+  {
+    if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+      /* then, not executed */
+    {
+      Int_Loc += 7;
+      Int_Glob = Int_Loc;
+      return (true);
+    }
+    else /* executed */
+      return (false);
+  } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3 (Enum_Par_Val)
+/***************************/
+    /* executed once        */
+    /* Enum_Par_Val == Ident_3 */
+Enumeration Enum_Par_Val;
+{
+  Enumeration Enum_Loc;
+
+  Enum_Loc = Enum_Par_Val;
+  if (Enum_Loc == Ident_3)
+    /* then, executed */
+    return (true);
+  else /* not executed */
+    return (false);
+} /* Func_3 */
+
Index: /branch/giet_vm_ioc_drivers/dhrystone/dhrystone.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/dhrystone/dhrystone.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/dhrystone/dhrystone.ld	(revision 283)
@@ -0,0 +1,38 @@
+/****************************************************************************
+* Definition of the base address for all virtual segments
+*****************************************************************************/
+
+seg_code_base      = 0x00400000;
+seg_data_base      = 0x00500000;
+
+/***************************************************************************
+* Grouping sections into segments for code and data
+***************************************************************************/
+
+SECTIONS
+{
+    . = seg_code_base;
+    seg_code : 
+    {
+        *(.text)
+    }
+    . = seg_data_base;
+    seg_data : 
+    {
+        *(.ctors)
+        *(.rodata)
+        /* . = ALIGN(4); */
+        *(.rodata.*)
+        /* . = ALIGN(4); */
+        *(.data)
+        /* . = ALIGN(4); */
+        *(.lit8)
+        *(.lit4)
+        *(.sdata)
+        /* . = ALIGN(4); */
+        *(.bss)
+        *(COMMON)
+        *(.sbss)
+        *(.scommon)
+    }
+}
Index: /branch/giet_vm_ioc_drivers/dhrystone/dhrystone.seg
===================================================================
--- /branch/giet_vm_ioc_drivers/dhrystone/dhrystone.seg	(revision 283)
+++ /branch/giet_vm_ioc_drivers/dhrystone/dhrystone.seg	(revision 283)
@@ -0,0 +1,26 @@
+265527
+24
+NAME=seg_boot_stack     ADDR=0x0000000000000000 SIZE=0x00004000 INIT=1
+NAME=seg_kernel_code    ADDR=0x0000000000004000 SIZE=0x00003f54 INIT=0
+NAME=seg_kernel_data    ADDR=0x0000000000008000 SIZE=0x00004000 INIT=0
+NAME=seg_kernel_uncdata ADDR=0x000000000000c000 SIZE=0x00000058 INIT=0
+NAME=seg_kernel_init    ADDR=0x000000000000d000 SIZE=0x00000564 INIT=0
+NAME=seg_sched          ADDR=0x000000000000e000 SIZE=0x00004000 INIT=1
+NAME=seg_data           ADDR=0x0000000000012000 SIZE=0x00003144 INIT=0
+NAME=seg_code           ADDR=0x0000000000016000 SIZE=0x00004bfc INIT=0
+NAME=seg_ptab           ADDR=0x000000000001b000 SIZE=0x00013000 INIT=1
+NAME=seg_stack_heap     ADDR=0x000000000002e000 SIZE=0x00020000 INIT=1
+NAME=seg_data           ADDR=0x000000000004e000 SIZE=0x00003144 INIT=0
+NAME=seg_code           ADDR=0x0000000000052000 SIZE=0x00004bfc INIT=0
+NAME=seg_ptab           ADDR=0x0000000000057000 SIZE=0x00013000 INIT=1
+NAME=seg_stack_heap     ADDR=0x000000000006a000 SIZE=0x00020000 INIT=1
+NAME=seg_data           ADDR=0x000000000008a000 SIZE=0x00003144 INIT=0
+NAME=seg_code           ADDR=0x000000000008e000 SIZE=0x00004bfc INIT=0
+NAME=seg_ptab           ADDR=0x0000000000093000 SIZE=0x00013000 INIT=1
+NAME=seg_stack_heap     ADDR=0x00000000000a6000 SIZE=0x00020000 INIT=1
+NAME=seg_data           ADDR=0x00000000000c6000 SIZE=0x00003144 INIT=0
+NAME=seg_code           ADDR=0x00000000000ca000 SIZE=0x00004bfc INIT=0
+NAME=seg_ptab           ADDR=0x00000000000cf000 SIZE=0x00013000 INIT=1
+NAME=seg_stack_heap     ADDR=0x00000000000e2000 SIZE=0x00020000 INIT=1
+NAME=seg_boot_code      ADDR=0x00000000bfc00000 SIZE=0x00005b30 INIT=0
+NAME=seg_boot_mapping   ADDR=0x00000000bfc08000 SIZE=0x00001f9c INIT=0
Index: /branch/giet_vm_ioc_drivers/display/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/display/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/display/Makefile	(revision 283)
@@ -0,0 +1,24 @@
+APP_NAME=display
+
+USE+= stdio.o
+
+USES=$(patsubst %,$(BUILD_PATH)/$(LIB_NAME)/%,$(USE))
+
+OBJS= main.o 
+
+all: $(APP_NAME).elf
+
+BIN_NAME_PATH=$(BUILD_PATH)$(APP_NAME).elf
+
+$(APP_NAME).elf: $(OBJS) $(APP_NAME).ld
+	$(LD) -o $(BIN_NAME_PATH) -T $(APP_NAME).ld $(OBJS) $(USES)
+	$(DU) -D $(BIN_NAME_PATH) > $@.txt
+
+%.o: %.c 
+	$(CC)  $(INCLUDE) $(CFLAGS) $($*.o_CFLAGS) -c -o  $@ $<
+	$(DU) -D  $@ >  $@.txt
+
+
+clean:
+	rm -f *.o *.elf *.txt core *~ 2>$(TRASH)
+	rm $(BIN_NAME_PATH) 2>$(TRASH)
Index: /branch/giet_vm_ioc_drivers/display/display.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/display/display.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/display/display.ld	(revision 283)
@@ -0,0 +1,39 @@
+/****************************************************************************
+* Definition of the base address for all virtual segments
+*****************************************************************************/
+
+seg_code_base      = 0x00400000;
+seg_data_base      = 0x00500000;	
+
+/***************************************************************************
+* Grouping sections into segments for code and data
+***************************************************************************/
+
+SECTIONS
+{
+    . = seg_code_base;
+    seg_code : 
+    {
+        *(.text)
+    }
+    . = seg_data_base;
+    seg_data : 
+    {
+        *(.ctors)
+        *(.rodata)
+        /* . = ALIGN(4); */
+        *(.rodata.*)
+        /* . = ALIGN(4); */
+        *(.data)
+        /* . = ALIGN(4); */
+        *(.lit8)
+        *(.lit4)
+        *(.sdata)
+        /* . = ALIGN(4); */
+        *(.bss)
+        *(COMMON)
+        *(.sbss)
+        *(.scommon)
+    }
+}
+
Index: /branch/giet_vm_ioc_drivers/display/main.c
===================================================================
--- /branch/giet_vm_ioc_drivers/display/main.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/display/main.c	(revision 283)
@@ -0,0 +1,67 @@
+#include <stdio.h>
+
+#define NBLOCKS 32   // (128 * 128) / 512
+
+unsigned char buf[128*128] __attribute__((aligned(512)));
+
+__attribute__((constructor)) void main()
+{  
+    int           fd;
+    int           blocks;
+    unsigned int  ko;
+    unsigned int  blocks_to_skip = 8*NBLOCKS;
+
+    giet_tty_printf("\nStarting task DISPLAY on processor %d at cycle %d\n",
+                    giet_procid(), giet_proctime() );
+
+    ///////////////////////////////////////////
+    fd = giet_fat_open( "misc/images.raw", 0 );
+    if ( fd < 0 )
+    {
+        giet_tty_printf("\n*** echec giet_fat_open for misc/images.raw at cycle %d\n", 
+                        giet_proctime() );
+        giet_exit();
+    }
+    else
+    {
+        giet_tty_printf("\ngiet_fat_open completed for misc/images.raw at cycle %d\n", 
+                        giet_proctime() );
+    }
+
+    /////////////////////////////////////////
+    while ( blocks_to_skip < (10 * NBLOCKS) )
+    {
+        // lecture image sur le disque
+        blocks = giet_fat_read( fd, buf, NBLOCKS, blocks_to_skip );
+        if ( blocks != NBLOCKS )
+        {
+            giet_tty_printf("\n*** echec giet_fat_read at cycle %d\n", 
+                            giet_proctime() );
+            giet_exit();
+        }
+        else
+        {
+            giet_tty_printf("\ngiet_fat_read for image %d completed at cycle %d \n", 
+                            (blocks_to_skip>>5), giet_proctime());
+        }
+
+        // transfert vers le frame buffer  
+        ko = giet_fb_sync_write( 0, buf, 128 * 128 );
+        if ( ko )
+        {
+            giet_tty_printf("\n*** echec giet_fb_sync_write at cycle %d\n", 
+                            giet_proctime() );
+            giet_exit();
+        }
+        else
+        {
+            giet_tty_printf("\ndisplay completed for image %d at cycle %d \n", 
+                            (blocks_to_skip>>5), giet_proctime());
+        }
+
+        blocks_to_skip = blocks_to_skip + NBLOCKS;
+    }
+
+    giet_tty_printf("\n*** Tak display exit at cycle %d ***\n", giet_proctime());
+    giet_exit();
+}
Index: /branch/giet_vm_ioc_drivers/display/main_cma.c
===================================================================
--- /branch/giet_vm_ioc_drivers/display/main_cma.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/display/main_cma.c	(revision 283)
@@ -0,0 +1,115 @@
+#include <stdio.h>
+
+#define NBLOCKS 32
+
+unsigned char buf0[128*128] __attribute__((aligned(512)));
+unsigned char buf1[128*128] __attribute__((aligned(512)));
+
+__attribute__((constructor)) void main(void)
+{
+    unsigned int ko;
+    int          blocks;
+    int          fd;
+    unsigned int blocks_to_skip = 0;
+
+    giet_tty_printf("\nStarting task DISPLAY on processor %d at cycle %d\n",
+                    giet_procid(), giet_proctime() );
+
+    //////////////////////////////////////////
+    fd = giet_fat_open( "misc/images.raw", 0 );
+    if ( fd < 0 )
+    {
+        giet_tty_printf("\n*** echec giet_fat_open for misc/images.raw at cycle %d\n", 
+                        giet_proctime() );
+        giet_exit();
+    }
+    else
+    {
+        giet_tty_printf("\ngiet_fat_open completed for misc/images.raw at cycle %d\n", 
+                        giet_proctime() );
+    }
+
+    ////////////////////////////////////////////
+    ko = giet_fb_cma_init( buf0, buf1, 128*128 );
+    if ( ko )
+    {
+        giet_tty_printf("\n*** echec giet_cma_init at cycle %d\n", 
+                        giet_proctime() );
+        giet_exit();
+    }
+    else
+    {
+        giet_tty_printf("\ngiet_cma_init completed at cycle %d\n", 
+                        giet_proctime() );
+    }
+
+ 
+    while ( blocks_to_skip < 10 * NBLOCKS )
+    {
+        ////////////////////////////////////////////////////////////
+        blocks = giet_fat_read( fd, buf0, NBLOCKS, blocks_to_skip );
+        if ( blocks != NBLOCKS )
+        {
+            giet_tty_printf("\nechec giet_fat_read to buf0 at cycle %d\n",
+                            giet_proctime() );
+            giet_exit();
+        }
+        else
+        {
+            giet_tty_printf("\ngiet_fat_read to buf0 completed at cycle = %d\n",
+                            giet_proctime() );
+        }
+
+        ///////////////////////////
+        ko = giet_fb_cma_write( 0 );
+        if ( ko )
+        {
+            giet_tty_printf("echec giet_cma_write for buf0 at cycle %d\n",
+                            giet_proctime() );
+            giet_exit();
+        }
+        else
+        {
+            giet_tty_printf("giet_cma_write for buf0 completed at cycle = %d\n",
+                            giet_proctime() );
+        }
+
+        blocks_to_skip = blocks_to_skip + NBLOCKS;
+
+        ///////////////////////////////////////////////////////
+        blocks = giet_fat_read( fd, buf1, NBLOCKS, blocks_to_skip );
+        if ( blocks != NBLOCKS )
+        {
+            giet_tty_printf("echec giet_fat_read to buf1 at cycle %d\n",
+                            giet_proctime() );
+            giet_exit();
+        }
+        else
+        {
+            giet_tty_printf("giet_fat_read to buf1 completed at cycle = %d\n",
+                            giet_proctime() );
+        }
+
+        ////////////////////////////
+        ko = giet_fb_cma_write( 1 );
+        if ( ko )
+        {
+            giet_tty_printf("echec giet_cma_write for buf1 at cycle %d\n",
+                            giet_proctime() );
+            giet_exit();
+        }
+        else
+        {
+            giet_tty_printf("giet_cma_write for buf1 completed at cycle = %d\n",
+                            giet_proctime() );
+        }
+        blocks_to_skip = blocks_to_skip + NBLOCKS;
+    }
+
+    ///////////////////
+    giet_fb_cma_stop();
+
+    giet_tty_printf("\n*** Task display exit at cycle %d ***\n", giet_proctime());
+
+    giet_exit();
+}
Index: /branch/giet_vm_ioc_drivers/gameoflife/gameoflife.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/gameoflife/gameoflife.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/gameoflife/gameoflife.ld	(revision 283)
@@ -0,0 +1,39 @@
+/****************************************************************************
+* Definition of the base address for all virtual segments
+*****************************************************************************/
+
+seg_data_base      = 0x00800000;
+seg_code_base      = 0x00400000;
+
+/***************************************************************************
+* Grouping sections into segments for code and data
+***************************************************************************/
+
+SECTIONS
+{
+    . = seg_code_base;
+    seg_code : 
+    {
+        *(.text)
+    }
+    . = seg_data_base;
+    seg_data : 
+    {
+        *(.ctors)
+        *(.rodata)
+        /* . = ALIGN(4); */
+        *(.rodata.*)
+        /* . = ALIGN(4); */
+        *(.data)
+        /* . = ALIGN(4); */
+        *(.lit8)
+        *(.lit4)
+        *(.sdata)
+        /* . = ALIGN(4); */
+        *(.bss)
+        *(COMMON)
+        *(.sbss)
+        *(.scommon)
+    }
+}
+
Index: /branch/giet_vm_ioc_drivers/gameoflife/main.c
===================================================================
--- /branch/giet_vm_ioc_drivers/gameoflife/main.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/gameoflife/main.c	(revision 283)
@@ -0,0 +1,177 @@
+/* 
+ * This application is an emulation of the game of life automaton
+ * It must be deployed from processor 0 and use contiguous processor
+ * (example 0,1,2,3) 
+ */
+
+
+#include "stdio.h"
+#include "limits.h"
+#include "barrier.h"
+#include "hard_config.h"
+#include "mapping_info.h"
+
+#define WIDTH           128
+#define HEIGHT          128
+#define NB_CLUSTER_MAX  256
+#define NB_ITERATION    1000000000
+
+#define PRINTF(...)      ({ if (giet_procid() == 0) { giet_tty_printf(__VA_ARGS__); } })
+
+giet_barrier_t barriers[2];
+
+#define NEW 0
+#define OLD 1
+
+typedef unsigned char uint8_t;
+typedef unsigned int size_t;
+
+uint8_t world[2][HEIGHT][WIDTH];
+uint8_t world_yuv[HEIGHT][WIDTH];
+
+/* Generate binary values for world between base_line and base_line + nb_line */
+void init_world(size_t base_line, size_t nb_line)
+{
+   size_t x,y;
+   for (y = base_line ; y < base_line + nb_line; y++){
+      for(x = 0; x < WIDTH ; x++) {
+         // TODO OPTIMIZE RANDOM INIT
+         world[OLD][y][x] = giet_rand() % 2;  
+      }
+   }
+}
+
+uint8_t number_of_alive_neigh(size_t x, size_t y)
+{
+   uint8_t nb = 0;
+
+   nb += world[OLD][(y - 1) % HEIGHT][(x - 1) % WIDTH];
+   nb += world[OLD][ y              ][(x - 1) % WIDTH];
+   nb += world[OLD][(y + 1) % HEIGHT][(x - 1) % WIDTH];
+   nb += world[OLD][(y - 1) % HEIGHT][ x             ];
+   nb += world[OLD][(y + 1) % HEIGHT][ x             ];
+   nb += world[OLD][(y - 1) % HEIGHT][(x + 1) % WIDTH];
+   nb += world[OLD][ y              ][(x + 1) % WIDTH];
+   nb += world[OLD][(y + 1) % HEIGHT][(x + 1) % WIDTH];
+
+   return nb;
+}
+
+/* Compute cell x,y */
+uint8_t compute_cell(size_t x, size_t y)
+{
+   uint8_t nb_neighbours_alive = number_of_alive_neigh(x,y);
+   if (world[OLD][y][x] == 1) {
+      if (nb_neighbours_alive == 2 ||
+          nb_neighbours_alive == 3) 
+      {
+         return 1;   
+      }
+   }
+   else {
+      if (nb_neighbours_alive == 3) {
+         return 1;
+      }
+      else {
+         return world[OLD][y][x];
+      }
+   }
+   return 0;
+}
+
+void compute_new_gen(size_t base_line, size_t nb_line)
+{
+   size_t x,y;
+   for (y = base_line; y < base_line + nb_line; y++){
+      for(x = 0; x < WIDTH ; x++) {
+         world[NEW][y][x] = compute_cell(x,y);  
+      }
+   }
+}
+
+void display_world(size_t base_line, size_t nb_line)
+{
+   size_t x,y;
+   for (y = base_line; y < base_line + nb_line; y++){
+      for(x = 0; x < WIDTH ; x++) {
+         //world_yuv[y][x] = world[NEW][y][x]*100;  
+         world[NEW][y][x] = world[NEW][y][x]*255;  
+      }
+   }
+
+   if (giet_fb_sync_write(base_line * WIDTH , &world[NEW][base_line][0], nb_line * WIDTH))
+   {
+      PRINTF("Echec fb_sync_write\n");
+      giet_exit();
+   }
+   // TODO COLOR !
+   /*if (giet_fb_sync_write(base_line * WIDTH + WIDTH*HEIGHT , &world_yuv[base_line][0], nb_line * WIDTH))
+   {
+      PRINTF("Echec fb_sync_write\n");
+      giet_exit();
+   }*/
+}
+
+void grow_old_world(size_t base_line, size_t nb_line)
+{
+   size_t x,y;
+   for (y = base_line; y < base_line + nb_line; y++){
+      for(x = 0; x < WIDTH ; x++) {
+         world[OLD][y][x] = world[NEW][y][x];  
+      }
+   }
+}
+
+
+
+////////////////////////////////////////
+__attribute__((constructor)) void main()
+{
+   unsigned int proc_id       = giet_procid();              // processor id
+   unsigned int nlocal_procs  = NB_PROCS_MAX;               // processors per cluster
+   unsigned int nclusters     = X_SIZE*Y_SIZE;              // number of clusters
+   unsigned int local_id      = proc_id % nlocal_procs;     // local processor id
+   unsigned int cluster_id    = proc_id / nlocal_procs;     // cluster id
+   unsigned int nglobal_procs = nclusters * nlocal_procs;   // number of tasks
+   size_t i;
+
+   size_t       nb_line       = HEIGHT / nglobal_procs;
+   size_t       base_line     = nb_line * proc_id; 
+   
+   PRINTF("*** Starting init at cycle %d ***\n", giet_proctime());
+
+   //  barriers initialization
+   barrier_init(&barriers[0], nglobal_procs);
+   barrier_init(&barriers[1], nglobal_procs);
+   init_world(base_line, nb_line);
+
+   PRINTF("*** Completing init at cycle %d ***\n", giet_proctime());
+   barrier_wait(&barriers[0]);
+   
+   for (i = 0; i < NB_ITERATION; i++)
+   {
+      //PRINTF("\n*** Starting computation for iteration %d at cycle %d\n", i, giet_proctime());
+      compute_new_gen(base_line, nb_line);
+      //PRINTF("\n*** Starting display for iteration %d at cycle %d\n", i, giet_proctime());
+      grow_old_world(base_line, nb_line);
+      display_world(base_line, nb_line);
+      barrier_wait(&barriers[1]);
+      barrier_init(&barriers[1], nglobal_procs);
+   }
+
+   PRINTF("*** End of main at cycle %d ***\n", giet_proctime());
+
+   giet_exit();
+} // end main()
+
+// Local Variables:
+// tab-width: 3
+// c-basic-offset: 3
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
+
+
+
Index: /branch/giet_vm_ioc_drivers/giet_boot/boot.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_boot/boot.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_boot/boot.c	(revision 283)
@@ -0,0 +1,2229 @@
+//////////////////////////////////////////////////////////////////////////////////////////
+// File     : boot.c
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+//////////////////////////////////////////////////////////////////////////////////////////
+// The boot.c file is part of the GIET-VM nano-kernel.
+//
+// This nano-kernel has been written for the MIPS32 processor.
+// The virtual adresses are on 32 bits and use the (unsigned int) type, but the 
+// physicals addresses can have up to 40 bits, and use the  (unsigned long long) type.
+// It natively supports clusterised shared mmemory multi-processors architectures, 
+// where each processor is identified by a composite index (cluster_xy, local_id),
+// and where there is one physical memory bank per cluster.
+//
+// This code is executed in the boot phase by proc[0] and performs the following tasks:
+// - load into memory the giet_vm binary files, contained in a FAT32 file system,
+// - build the various page tables (one page table per vspace) 
+// - initialize the shedulers (one scheduler per processor)
+//
+// 1) The binary files to be loaded are:
+//    - the "map.bin" file contains the hardware architecture description and the
+//      mapping directives. It must be stored in the the seg_boot_mapping segment 
+//      (at address seg_boot_mapping_base).
+//    - the "sys.elf" file contains the kernel binary code and data.
+//    - the various "application.elf" files.
+//
+// 2) The map.bin file contains the binary representation of the map.xml file defining: 
+//    - the hardware architecture: number of clusters, number or processors, 
+//      size of the memory segments, and peripherals in each cluster.
+//    - The structure of the various multi-threaded software applications:
+//      number of tasks, communication channels.
+//    - The mapping: placement of virtual objects (vobj) in the virtual segments (vseg),
+//      placement of virtual segments (vseg) in the physical segments (pseg), placement 
+//      of software tasks on the processors, 
+//
+// 3) The GIET-VM uses the paged virtual memory to provides two services:
+//    - classical memory protection, when several independant applications compiled
+//      in different virtual spaces are executing on the same hardware platform.
+//    - data placement in NUMA architectures, when we want to control the placement 
+//      of the software objects (virtual segments) on the physical memory banks.
+//
+//    The page table are statically build in the boot phase, and they do not 
+//    change during execution. The GIET uses only 4 Kbytes pages.
+//    As most applications use only a limited number of segments, the number of PT2s 
+//    actually used by a given virtual space is generally smaller than 2048, and is
+//    computed during the boot phase.
+//    The max number of virtual spaces (GIET_NB_VSPACE_MAX) is a configuration parameter.
+//
+//    Each page table (one page table per virtual space) is monolithic, and contains 
+//    one PT1 and up to (GIET_NB_PT2_MAX) PT2s. The PT1 is addressed using the ix1 field
+//    (11 bits) of the VPN, and the selected PT2 is addressed using the ix2 field (9 bits).
+//    - PT1[2048] : a first 8K aligned array of unsigned int, indexed by (ix1) field of VPN. 
+//    Each entry in the PT1 contains a 32 bits PTD. The MSB bit PTD[31] is 
+//    the PTD valid bit, and LSB bits PTD[19:0] are the 20 MSB bits of the physical base
+//    address of the selected PT2.
+//    The PT1 contains 2048 PTD of 4 bytes => 8K bytes.
+//    - PT2[1024][GIET_NB_PT2_MAX] : an array of array of unsigned int. 
+//    Each PT2[1024] must be 4K aligned, each entry in a PT2 contains two unsigned int: 
+//    the first word contains the protection flags, and the second word contains the PPN.
+//    Each PT2 contains 512 PTE2 of 8bytes => 4K bytes.
+//    The total size of a page table is finally = 8K + (GIET_NB_PT2_MAX)*4K bytes.
+///////////////////////////////////////////////////////////////////////////////////////
+// Implementation Notes:
+//
+// 1) The cluster_id variable is a linear index in the mapping_info array of clusters. 
+//    We use the cluster_xy variable for the tological index = x << Y_WIDTH + y
+///////////////////////////////////////////////////////////////////////////////////////
+
+// for vobjs initialisation
+#include <giet_config.h>
+#include <mwmr_channel.h>
+#include <barrier.h>
+#include <memspace.h>
+#include <tty_driver.h>
+#include <xcu_driver.h>
+#include <ioc_driver.h>
+#include <dma_driver.h>
+#include <cma_driver.h>
+#include <nic_driver.h>
+#include <ioc_driver.h>
+#include <mwr_driver.h>
+#include <ctx_handler.h>
+#include <irq_handler.h>
+#include <vmem.h>
+#include <utils.h>
+#include <elf-types.h>
+
+// for boot FAT initialisation 
+#include <fat32.h>
+
+#include <mips32_registers.h>
+#include <stdarg.h>
+
+#if !defined(X_SIZE)
+# error The X_SIZE value must be defined in the 'hard_config.h' file !
+#endif
+
+#if !defined(Y_SIZE)
+# error The Y_SIZE value must be defined in the 'hard_config.h' file !
+#endif
+
+#if !defined(X_WIDTH)
+# error The X_WIDTH value must be defined in the 'hard_config.h' file !
+#endif
+
+#if !defined(Y_WIDTH)
+# error The Y_WIDTH value must be defined in the 'hard_config.h' file !
+#endif
+
+#if !defined(NB_PROCS_MAX)
+# error The NB_PROCS_MAX value must be defined in the 'hard_config.h' file !
+#endif
+
+#if !defined(GIET_NB_VSPACE_MAX)
+# error The GIET_NB_VSPACE_MAX value must be defined in the 'giet_config.h' file !
+#endif
+
+////////////////////////////////////////////////////////////////////////////
+//      Global variables for boot code
+// Both the page tables for the various virtual spaces, and the schedulers
+// for the processors are physically distributed on the clusters.
+// These global variables are just arrays of pointers. 
+////////////////////////////////////////////////////////////////////////////
+
+// This global variable is allocated in "fat32.c" file
+extern fat32_fs_t fat;
+
+// Page table addresses arrays
+__attribute__((section (".bootdata"))) 
+paddr_t      _ptabs_paddr[GIET_NB_VSPACE_MAX];
+
+__attribute__((section (".bootdata"))) 
+unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];
+
+// Next free PT2 index array
+__attribute__((section (".bootdata"))) 
+unsigned int _next_free_pt2[GIET_NB_VSPACE_MAX] =
+{ [0 ... GIET_NB_VSPACE_MAX - 1] = 0 };
+
+// Max PT2 index 
+__attribute__((section (".bootdata"))) 
+unsigned int _max_pt2[GIET_NB_VSPACE_MAX] =
+{ [0 ... GIET_NB_VSPACE_MAX - 1] = 0 };
+
+// Scheduler pointers array (virtual addresses)
+// indexed by (x,y,lpid) : ((x << Y_WIDTH) + y)*NB_PROCS_MAX + lpid
+__attribute__((section (".bootdata"))) 
+static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)];
+
+
+/////////////////////////////////////////////////////////////////////
+// This function checks consistence beween the  mapping_info data 
+// structure (soft), and the giet_config file (hard).
+/////////////////////////////////////////////////////////////////////
+void boot_mapping_check() 
+{
+    mapping_header_t * header = (mapping_header_t *) & seg_boot_mapping_base;
+
+    // checking mapping availability
+    if (header->signature != IN_MAPPING_SIGNATURE) 
+    {
+        _puts("\n[BOOT ERROR] Illegal mapping signature: ");
+        _putx(header->signature);
+        _puts("\n");
+        _exit();
+    }
+
+    // checking number of clusters
+    if ( (header->x_size  != X_SIZE)  || 
+         (header->y_size  != Y_SIZE)  ||
+         (header->x_width != X_WIDTH) ||
+         (header->y_width != Y_WIDTH) )
+    {
+        _puts("\n[BOOT ERROR] Incoherent X_SIZE or Y_SIZE ");
+        _puts("\n             - In hard_config:  X_SIZE = ");
+        _putd( X_SIZE );
+        _puts(" / Y_SIZE = ");
+        _putd( Y_SIZE );
+        _puts(" / X_WIDTH = ");
+        _putd( X_WIDTH );
+        _puts(" / Y_WIDTH = ");
+        _putd( Y_WIDTH );
+        _puts("\n             - In mapping_info: x_size = ");
+        _putd( header->x_size );
+        _puts(" / y_size = ");
+        _putd( header->y_size );
+        _puts(" / x_width = ");
+        _putd( header->x_width );
+        _puts(" / y_width = ");
+        _putd( header->y_width );
+        _puts("\n");
+        _exit();
+    }
+    // checking number of virtual spaces
+    if (header->vspaces > GIET_NB_VSPACE_MAX) 
+    {
+        _puts("\n[BOOT ERROR] : number of vspaces > GIET_NB_VSPACE_MAX\n");
+        _puts("\n");
+        _exit();
+    }
+
+#if BOOT_DEBUG_MAPPING
+_puts("\n - x_size    = ");
+_putd( header->x_size );
+_puts("\n - y_size    = ");
+_putd( header->y_size );
+_puts("\n - procs     = ");
+_putd( header->procs );
+_puts("\n - periphs   = ");
+_putd( header->periphs );
+_puts("\n - vspaces   = ");
+_putd( header->vspaces );
+_puts("\n - tasks     = ");
+_putd( header->tasks );
+_puts("\n");
+_puts("\n - size of header  = ");
+_putd( MAPPING_HEADER_SIZE );
+_puts("\n - size of cluster = ");
+_putd( MAPPING_CLUSTER_SIZE );
+_puts("\n - size of pseg    = ");
+_putd( MAPPING_PSEG_SIZE );
+_puts("\n - size of proc    = ");
+_putd( MAPPING_PROC_SIZE );
+_puts("\n - size of vspace  = ");
+_putd( MAPPING_VSPACE_SIZE );
+_puts("\n - size of vseg    = ");
+_putd( MAPPING_VSEG_SIZE );
+_puts("\n - size of vobj    = ");
+_putd( MAPPING_VOBJ_SIZE );
+_puts("\n - size of task    = ");
+_putd( MAPPING_TASK_SIZE );
+_puts("\n");
+
+unsigned int cluster_id;
+mapping_cluster_t * cluster = _get_cluster_base(header);
+for( cluster_id = 0; cluster_id < X_SIZE*Y_SIZE ; cluster_id++) 
+{
+    _puts("\n - cluster[");
+    _putd( cluster[cluster_id].x );
+    _puts(",");
+    _putd( cluster[cluster_id].y );
+    _puts("]\n   procs   = ");
+    _putd( cluster[cluster_id].procs );
+    _puts("\n   psegs   = ");
+    _putd( cluster[cluster_id].psegs );
+    _puts("\n   periphs = ");
+    _putd( cluster[cluster_id].periphs );
+    _puts("\n");
+}
+#endif
+
+} // end boot_mapping_check()
+
+
+//////////////////////////////////////////////////////////////////////////////
+//     boot_pseg_get() 
+// This function returns the pointer on a physical segment
+// identified  by the pseg index.
+//////////////////////////////////////////////////////////////////////////////
+mapping_pseg_t *boot_pseg_get(unsigned int seg_id) 
+{
+    mapping_header_t* header = (mapping_header_t*)(&seg_boot_mapping_base);
+    mapping_pseg_t * pseg    = _get_pseg_base(header);
+
+    // checking argument
+    if (seg_id >= header->psegs) 
+    {
+        _puts("\n[BOOT ERROR] : seg_id argument too large\n");
+        _puts("               in function boot_pseg_get()\n");
+        _exit();
+    }
+
+    return &pseg[seg_id];
+}  
+
+//////////////////////////////////////////////////////////////////////////////
+// boot_add_pte() 
+// This function registers a new PTE in the page table defined
+// by the vspace_id argument, and updates both PT1 and PT2.
+// A new PT2 is used when required.
+// As the set of PT2s is implemented as a fixed size array (no dynamic 
+// allocation), this function checks a possible overflow of the PT2 array.
+//////////////////////////////////////////////////////////////////////////////
+void boot_add_pte(unsigned int vspace_id,
+                  unsigned int vpn, 
+                  unsigned int flags, 
+                  unsigned int ppn,
+                  unsigned int verbose) 
+{
+    unsigned int ix1;
+    unsigned int ix2;
+    paddr_t      pt1_pbase;     // PT1 physical base address
+    paddr_t      pt2_pbase;     // PT2 physical base address
+    paddr_t      pte_paddr;     // PTE physucal address
+    unsigned int pt2_id;        // PT2 index
+    unsigned int ptd;           // PTD : entry in PT1
+    unsigned int max_pt2;       // max number of PT2s for a given vspace
+
+    ix1 = vpn >> 9;         // 11 bits
+    ix2 = vpn & 0x1FF;      //  9 bits
+
+    // check that the _max_pt2[vspace_id] has been set
+    max_pt2 = _max_pt2[vspace_id];
+
+    if (max_pt2 == 0) 
+    {
+        _puts("Undefined page table for vspace ");
+        _putd(vspace_id);
+        _puts("\n");
+        _exit();
+    }
+
+
+    // get page table physical base address
+    pt1_pbase = _ptabs_paddr[vspace_id];
+
+    // get ptd in PT1
+    ptd = _physical_read(pt1_pbase + 4 * ix1);
+
+    if ((ptd & PTE_V) == 0)    // invalid PTD: compute PT2 base address, 
+                               // and set a new PTD in PT1 
+    {
+        pt2_id = _next_free_pt2[vspace_id];
+        if (pt2_id == max_pt2) 
+        {
+            _puts("\n[BOOT ERROR] in boot_add_pte() function\n");
+            _puts("the length of the ptab vobj is too small\n");
+
+            _puts(" max_pt2 = ");
+            _putd( max_pt2 );
+            _puts("\n");
+            _puts(" pt2_id  = ");
+            _putd( pt2_id );
+            _puts("\n");
+            
+            _exit();
+        }
+        else 
+        {
+            pt2_pbase = pt1_pbase + PT1_SIZE + PT2_SIZE * pt2_id;
+            ptd = PTE_V | PTE_T | (unsigned int) (pt2_pbase >> 12);
+            _physical_write( pt1_pbase + 4 * ix1, ptd);
+            _next_free_pt2[vspace_id] = pt2_id + 1;
+        }
+    }
+    else                       // valid PTD: compute PT2 base address
+    {
+        pt2_pbase = ((paddr_t)(ptd & 0x0FFFFFFF)) << 12;
+    }
+
+    // set PTE in PT2 : flags & PPN in two 32 bits words
+    pte_paddr = pt2_pbase + 8 * ix2;
+    _physical_write(pte_paddr    , flags);
+    _physical_write(pte_paddr + 4, ppn);
+
+    if (verbose)
+    {
+        _puts(" / vpn = ");
+        _putx( vpn );
+        _puts(" / ix1 = ");
+        _putx( ix1 );
+        _puts(" / ix2 = ");
+        _putx( ix2 );
+        _puts(" / pt1_pbase = ");
+        _putl( pt1_pbase );
+        _puts(" / ptd = ");
+        _putl( ptd );
+        _puts(" / pt2_pbase = ");
+        _putl( pt2_pbase );
+        _puts(" / pte_paddr = ");
+        _putl( pte_paddr );
+        _puts(" / ppn = ");
+        _putx( ppn );
+        _puts("/\n");
+    }
+
+}   // end boot_add_pte()
+
+
+/////////////////////////////////////////////////////////////////////
+// This function build the page table for a given vspace. 
+// The physical base addresses for all vsegs (global and private)
+// must have been previously computed and stored in the mapping.
+// It initializes the MWMR channels.
+/////////////////////////////////////////////////////////////////////
+void boot_vspace_pt_build(unsigned int vspace_id) 
+{
+    unsigned int vseg_id;
+    unsigned int npages;
+    unsigned int ppn;
+    unsigned int vpn;
+    unsigned int flags;
+    unsigned int page_id;
+    unsigned int verbose = 0;   // can be used to activate trace in add_pte()
+
+    mapping_header_t * header = (mapping_header_t *) & seg_boot_mapping_base;
+    mapping_vspace_t * vspace = _get_vspace_base(header);
+    mapping_vseg_t   * vseg   = _get_vseg_base(header);
+
+    // private segments
+    for (vseg_id = vspace[vspace_id].vseg_offset;
+         vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
+         vseg_id++) 
+    {
+        vpn = vseg[vseg_id].vbase >> 12;
+        ppn = (unsigned int) (vseg[vseg_id].pbase >> 12);
+
+        npages = vseg[vseg_id].length >> 12;
+        if ((vseg[vseg_id].length & 0xFFF) != 0) npages++; 
+
+        flags = PTE_V;
+        if (vseg[vseg_id].mode & C_MODE_MASK) flags = flags | PTE_C;
+        if (vseg[vseg_id].mode & X_MODE_MASK) flags = flags | PTE_X;
+        if (vseg[vseg_id].mode & W_MODE_MASK) flags = flags | PTE_W;
+        if (vseg[vseg_id].mode & U_MODE_MASK) flags = flags | PTE_U;
+
+#if BOOT_DEBUG_PT
+        _puts(vseg[vseg_id].name);
+        _puts(" : flags = ");
+        _putx(flags);
+        _puts(" / npages = ");
+        _putd(npages);
+        _puts(" / pbase = ");
+        _putl(vseg[vseg_id].pbase);
+        _puts("\n");
+#endif
+        // loop on 4K pages
+        for (page_id = 0; page_id < npages; page_id++) 
+        {
+            boot_add_pte(vspace_id, vpn, flags, ppn, verbose);
+            vpn++;
+            ppn++;
+        }
+    }
+
+    // global segments
+    for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 
+    {
+        vpn = vseg[vseg_id].vbase >> 12;
+        ppn = (unsigned int)(vseg[vseg_id].pbase >> 12);
+        npages = vseg[vseg_id].length >> 12;
+        if ((vseg[vseg_id].length & 0xFFF) != 0) npages++;
+
+        flags = PTE_V;
+        if (vseg[vseg_id].mode & C_MODE_MASK)  flags = flags | PTE_C;
+        if (vseg[vseg_id].mode & X_MODE_MASK)  flags = flags | PTE_X;
+        if (vseg[vseg_id].mode & W_MODE_MASK)  flags = flags | PTE_W;
+        if (vseg[vseg_id].mode & U_MODE_MASK)  flags = flags | PTE_U;
+
+#if BOOT_DEBUG_PT
+        _puts(vseg[vseg_id].name);
+        _puts(" : flags = ");
+        _putx(flags);
+        _puts(" / npages = ");
+        _putd(npages);
+        _puts(" / pbase = ");
+        _putl(vseg[vseg_id].pbase);
+        _puts("\n");
+#endif
+        // loop on 4K pages
+        for (page_id = 0; page_id < npages; page_id++) 
+        {
+            boot_add_pte(vspace_id, vpn, flags, ppn, verbose);
+            vpn++;
+            ppn++;
+        }
+    }
+}   // end boot_vspace_pt_build()
+
+
+///////////////////////////////////////////////////////////////////////////
+// Align the value of paddr or vaddr to the required alignement,
+// defined by alignPow2 == L2(alignement).
+///////////////////////////////////////////////////////////////////////////
+paddr_t paddr_align_to(paddr_t paddr, unsigned int alignPow2) 
+{
+    paddr_t mask = (1 << alignPow2) - 1;
+    return ((paddr + mask) & ~mask);
+}
+
+unsigned int vaddr_align_to(unsigned int vaddr, unsigned int alignPow2) 
+{
+    unsigned int mask = (1 << alignPow2) - 1;
+    return ((vaddr + mask) & ~mask);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Set pbase for a vseg when identity mapping is required.
+// The length of the vseg must be known.
+// The ordered linked list of vsegs mapped on pseg must be updated,
+// and overlap with previously mapped vsegs must be checked.
+///////////////////////////////////////////////////////////////////////////
+void boot_vseg_set_paddr_ident(mapping_vseg_t * vseg) 
+{
+    // checking vseg not already mapped
+    if (vseg->mapped != 0) 
+    {
+        _puts("\n[BOOT ERROR] in boot_vseg_set_paddr_ident() : vseg ");
+        _puts( vseg->name );
+        _puts(" already mapped\n");
+        _exit();
+    }
+
+    // computes selected pseg pointer 
+    mapping_pseg_t* pseg = boot_pseg_get( vseg->psegid );
+
+    // computes vseg alignment constraint
+    mapping_header_t* header    = (mapping_header_t*)&seg_boot_mapping_base;
+    mapping_vobj_t*   vobj_base = _get_vobj_base( header );
+    unsigned int      align     = vobj_base[vseg->vobj_offset].align;
+    if ( vobj_base[vseg->vobj_offset].align < 12 ) align = 12;
+
+    // computes required_pbase for identity mapping,
+    paddr_t required_pbase = (paddr_t)vseg->vbase;
+
+    // checks identity constraint against alignment constraint
+    if ( paddr_align_to( required_pbase, align) != required_pbase )
+    {
+        _puts("\n[BOOT ERROR] in boot_vseg_set_paddr_ident() : vseg ");
+        _puts( vseg->name );
+        _puts(" has uncompatible identity and alignment constraints\n");
+        _exit();
+    }
+
+    // We are looking for a contiguous space in target pseg.
+    // If there is vsegs already mapped, we scan the vsegs list to: 
+    // - check overlap with already mapped vsegs,
+    // - try mapping in holes between already mapped vsegs,
+    // - update the ordered linked list if success
+    // We don't enter the loop if no vsegs is already mapped.
+    // implementation note: The next_vseg field is unsigned int,
+    // but we use it to store a MIP32 pointer on a vseg...
+
+    mapping_vseg_t*   curr      = 0;
+    mapping_vseg_t*   prev      = 0;
+    unsigned int      min_pbase = pseg->base;
+
+    for ( curr = (mapping_vseg_t*)pseg->next_vseg ; 
+          (curr != 0) && (vseg->mapped == 0) ; 
+          curr = (mapping_vseg_t*)curr->next_vseg )
+    {
+        // looking before current vseg
+        if( (required_pbase >= min_pbase) && 
+            (curr->pbase >= (required_pbase + vseg->length)) ) // space found
+        {
+            vseg->pbase  = required_pbase;
+            vseg->mapped = 1;
+
+            // update linked list
+            vseg->next_vseg = (unsigned int)curr;
+            if( curr == (mapping_vseg_t*)pseg->next_vseg ) 
+                pseg->next_vseg = (unsigned int)vseg;
+            else
+                prev->next_vseg = (unsigned int)vseg;
+        }
+        else                                         // looking in space after curr
+        {
+            prev = curr;
+            min_pbase = curr->pbase + curr->length;
+        }
+    }
+
+    // no success in the loop
+    if( (vseg->mapped == 0) &&
+        (required_pbase >= min_pbase) && 
+        ((required_pbase + vseg->length) <= (pseg->base + pseg->length)) )
+    {
+        vseg->pbase  = required_pbase;
+        vseg->mapped = 1;
+
+        // update linked list
+        vseg->next_vseg = 0;
+        if ((curr == 0) && (prev == 0)) pseg->next_vseg = (unsigned int)vseg;
+        else                            prev->next_vseg = (unsigned int)vseg;
+    }
+
+    if( vseg->mapped == 0 )
+    {
+        _puts("\n[BOOT ERROR] in boot_vseg_set_paddr_ident() : vseg ");
+        _puts( vseg->name );
+        _puts(" cannot be mapped on pseg ");
+        _puts( pseg->name );
+        _puts("\n");
+        _exit();
+    }
+}  // end boot_vseg_set_paddr_ident()
+
+                
+////////////////////////////////////////////////////////////////////////////
+// Set pbase for a vseg when there is no identity mapping constraint.
+// This is the physical memory allocator (written by Q.Meunier).
+// The length of the vseg must be known.
+// All identity mapping vsegs must be already mapped.
+// We use a linked list of already mapped vsegs, ordered by incresing pbase.
+// We try to place the vseg in the "first fit" hole in this list.
+////////////////////////////////////////////////////////////////////////////
+void boot_vseg_set_paddr(mapping_vseg_t * vseg) 
+{
+    // checking vseg not already mapped
+    if ( vseg->mapped != 0 ) 
+    {
+        _puts("\n[BOOT ERROR] in boot_vseg_set_paddr() : vseg ");
+        _puts( vseg->name );
+        _puts(" already mapped\n");
+        _exit();
+    }
+
+    // computes selected pseg pointer 
+    mapping_pseg_t*   pseg      = boot_pseg_get( vseg->psegid );
+
+    // computes vseg alignment constraint
+    mapping_header_t* header    = (mapping_header_t*)&seg_boot_mapping_base;
+    mapping_vobj_t*   vobj_base = _get_vobj_base( header );
+    unsigned int      align     = vobj_base[vseg->vobj_offset].align;
+    if ( vobj_base[vseg->vobj_offset].align < 12 ) align = 12;
+
+    // initialise physical base address, with alignment constraint
+    paddr_t possible_pbase = paddr_align_to( pseg->base, align );
+
+    // We are looking for a contiguous space in target pseg
+    // If there is vsegs already mapped, we scan the vsegs list to: 
+    // - try mapping in holes between already mapped vsegs,
+    // - update the ordered linked list if success
+    // We don't enter the loop if no vsegs is already mapped.
+    // implementation note: The next_vseg field is unsigned int,
+    // but we use it to store a MIP32 pointer on a vseg...
+
+    mapping_vseg_t*   curr = 0;
+    mapping_vseg_t*   prev = 0;
+
+    for( curr = (mapping_vseg_t*)pseg->next_vseg ; 
+         (curr != 0) && (vseg->mapped == 0) ; 
+         curr = (mapping_vseg_t*)curr->next_vseg )
+    {
+        // looking for space before current vseg
+        if ( (curr->pbase >= possible_pbase + vseg->length) ) // space before curr
+        {
+            vseg->pbase  = possible_pbase;
+            vseg->mapped = 1;
+
+            // update linked list
+            vseg->next_vseg = (unsigned int)curr;
+            if( curr == (mapping_vseg_t*)pseg->next_vseg ) 
+                pseg->next_vseg = (unsigned int)vseg;
+            else
+                prev->next_vseg = (unsigned int)vseg;
+        }
+        else                                            // looking for space after curr
+        {
+            possible_pbase = paddr_align_to( curr->pbase + curr->length, align );
+            prev           = curr;
+        }
+    }
+        
+    // when no space found, try to allocate space after already mapped vsegs
+    if( (vseg->mapped == 0) &&
+        ((possible_pbase + vseg->length) <= (pseg->base + pseg->length)) )
+    {
+        vseg->pbase  = possible_pbase;
+        vseg->mapped = 1;
+
+        // update linked list
+        vseg->next_vseg = 0;
+        if ((curr == 0 ) && (prev == 0)) pseg->next_vseg = (unsigned int)vseg;
+        else                             prev->next_vseg = (unsigned int)vseg;
+    }
+
+    if( vseg->mapped == 0 )
+    {
+        _puts("\n[BOOT ERROR] in boot_vseg_set_paddr() : vseg ");
+        _puts( vseg->name );
+        _puts(" cannot be mapped on pseg ");
+        _puts( pseg->name );
+        _puts("\n");
+        _exit();
+    }
+}  // end boot_vseg_set_paddr()
+
+///////////////////////////////////////////////////////////////////////////
+// This function computes the physical base address for a vseg
+// as specified in the mapping info data structure.
+// It updates the pbase and the length fields of the vseg.
+// It updates the pbase and vbase fields of all vobjs in the vseg.
+// It updates the _ptabs_paddr[] and _ptabs_vaddr[] arrays. 
+// It is a global vseg if vspace_id = (-1). 
+///////////////////////////////////////////////////////////////////////////
+void boot_vseg_map(mapping_vseg_t * vseg, unsigned int vspace_id) 
+{
+    unsigned int vobj_id;
+    unsigned int cur_vaddr;
+    paddr_t      cur_paddr;
+    paddr_t      cur_length;
+    unsigned int offset;
+
+    mapping_header_t * header = (mapping_header_t *) & seg_boot_mapping_base;
+    mapping_vobj_t   * vobj   = _get_vobj_base(header);
+
+    // loop on the vobjs contained in vseg to compute 
+    // the vseg length, required for mapping.
+    cur_length = 0;
+    for ( vobj_id = vseg->vobj_offset; 
+          vobj_id < (vseg->vobj_offset + vseg->vobjs); 
+          vobj_id++ ) 
+    {
+        if (vobj[vobj_id].align)
+        {
+            cur_length = vaddr_align_to(cur_length, vobj[vobj_id].align);
+        }
+        cur_length += vobj[vobj_id].length;
+    }
+    vseg->length = paddr_align_to(cur_length, 12);
+
+    // mapping: computes vseg pbase address
+    if (vseg->ident != 0)                         // identity mapping 
+    {
+        boot_vseg_set_paddr_ident( vseg );
+    }
+    else                                          // unconstrained mapping
+    {
+        boot_vseg_set_paddr( vseg );
+    }
+
+    // second loop on vobjs contained in vseg to :
+    // initialize the vaddr and paddr fields of all vobjs,
+    // and initialize the page table pointers arrays 
+
+    cur_vaddr = vseg->vbase;
+    cur_paddr = vseg->pbase;
+
+    for (vobj_id = vseg->vobj_offset; 
+         vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++) 
+    {
+        if (vobj[vobj_id].align) 
+        {
+            cur_paddr = paddr_align_to(cur_paddr, vobj[vobj_id].align);
+            cur_vaddr = vaddr_align_to(cur_vaddr, vobj[vobj_id].align);
+        }
+        // set vaddr/paddr for current vobj
+        vobj[vobj_id].vaddr = cur_vaddr;
+        vobj[vobj_id].paddr = cur_paddr;
+        
+        // initialize _ptabs_vaddr[] & boot_ptabs-paddr[] if PTAB
+        if (vobj[vobj_id].type == VOBJ_TYPE_PTAB) 
+        {
+            if (vspace_id == ((unsigned int) -1))    // global vseg
+            {
+                _puts("\n[BOOT ERROR] in boot_vseg_map() function: ");
+                _puts("a PTAB vobj cannot be global");
+                _exit();
+            }
+            // we need at least one PT2
+            if (vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE)) 
+            {
+                _puts("\n[BOOT ERROR] in boot_vseg_map() function, ");
+                _puts("PTAB too small, minumum size is: ");
+                _putx(PT1_SIZE + PT2_SIZE);
+                _exit();
+            }
+            // register both physical and virtual page table address
+            _ptabs_vaddr[vspace_id] = vobj[vobj_id].vaddr;
+            _ptabs_paddr[vspace_id] = vobj[vobj_id].paddr;
+            
+            // reset all valid bits in PT1
+            for ( offset = 0 ; offset < 8192 ; offset = offset + 4)
+            {
+                _physical_write(cur_paddr + offset, 0);
+            }
+
+            // computing the number of second level pages
+            _max_pt2[vspace_id] = (vobj[vobj_id].length - PT1_SIZE) / PT2_SIZE;
+        }
+
+        // set next vaddr/paddr
+        cur_vaddr = cur_vaddr + vobj[vobj_id].length;
+        cur_paddr = cur_paddr + vobj[vobj_id].length;
+    } // end for vobjs
+
+}    // end boot_vseg_map()
+
+/////////////////////////////////////////////////////////////////////
+// This function builds the page tables for all virtual spaces 
+// defined in the mapping_info data structure, in three steps:
+// - step 1 : It computes the physical base address for global vsegs
+//            and for all associated vobjs.
+// - step 2 : It computes the physical base address for all private 
+//            vsegs and all vobjs in each virtual space.
+// - step 3 : It actually fill the page table for each vspace.
+//
+// Note: It must exist at least one vspace in the mapping_info...
+/////////////////////////////////////////////////////////////////////
+void boot_pt_init() 
+{
+    mapping_header_t * header = (mapping_header_t *) &seg_boot_mapping_base;
+    mapping_vspace_t * vspace = _get_vspace_base(header);
+    mapping_vseg_t   * vseg   = _get_vseg_base(header);
+
+    unsigned int vspace_id;
+    unsigned int vseg_id;
+
+    if (header->vspaces == 0 )
+    {
+        _puts("\n[BOOT ERROR] in boot_pt_init() : mapping ");
+        _puts( header->name );
+        _puts(" contains no vspace\n");
+        _exit();
+    }
+
+#if BOOT_DEBUG_PT
+_puts("\n[BOOT DEBUG] ****** mapping global vsegs ******\n");
+#endif
+
+    // step 1 : loop on global vsegs 
+
+    // vsegs with identity mapping constraint first
+    for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 
+    {
+        if (vseg[vseg_id].ident == 1) 
+            boot_vseg_map(&vseg[vseg_id], ((unsigned int) (-1)));
+    }
+
+    // unconstrained vsegs second
+    for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 
+    {
+        if (vseg[vseg_id].ident == 0) 
+            boot_vseg_map(&vseg[vseg_id], ((unsigned int) (-1)));
+    }
+
+    // step 2 : loop on virtual vspaces to map private vsegs
+    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
+    {
+
+#if BOOT_DEBUG_PT
+_puts("\n[BOOT DEBUG] ****** mapping private vsegs in vspace ");
+_puts(vspace[vspace_id].name);
+_puts(" ******\n");
+#endif
+
+        // vsegs with identity mapping constraint first
+        for (vseg_id = vspace[vspace_id].vseg_offset;
+             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
+             vseg_id++) 
+        {
+            if (vseg[vseg_id].ident == 1) 
+                boot_vseg_map(&vseg[vseg_id], vspace_id);
+        }
+        // unconstrained vsegs second
+        for (vseg_id = vspace[vspace_id].vseg_offset;
+             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
+             vseg_id++) 
+        {
+            if (vseg[vseg_id].ident == 0)
+                boot_vseg_map(&vseg[vseg_id], vspace_id);
+        }
+    }
+
+#if BOOT_DEBUG_PT
+mapping_vseg_t* curr;
+mapping_pseg_t* pseg = _get_pseg_base(header);
+unsigned int    pseg_id;
+for( pseg_id = 0 ; pseg_id < header->psegs ; pseg_id++ )
+{
+    _puts("\n[BOOT DEBUG] ****** vsegs mapped on pseg ");
+    _puts( pseg[pseg_id].name );
+    _putd( pseg[pseg_id].clusterid);
+    _puts(" ******\n");
+    for( curr = (mapping_vseg_t*)pseg[pseg_id].next_vseg ;
+         curr != 0 ;
+         curr = (mapping_vseg_t*)curr->next_vseg )
+    {
+        _puts(" - vseg ");
+        _puts( curr->name );
+        _puts(" : len = ");
+        _putx( curr->length );
+        _puts(" / vbase ");
+        _putl( curr->vbase );
+        _puts(" / pbase ");
+        _putl( curr->pbase );
+        _puts("\n");
+    }  
+}
+#endif
+
+    // step 3 : loop on the vspaces to build the page tables
+    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
+    {
+
+#if BOOT_DEBUG_PT
+_puts("\n[BOOT DEBUG] ****** building page table for vspace ");
+_puts(vspace[vspace_id].name);
+_puts(" ******\n");
+#endif
+
+        boot_vspace_pt_build(vspace_id);
+
+        _puts("\n[BOOT] Page Table for vspace ");
+        _puts( vspace[vspace_id].name );
+        _puts(" completed at cycle ");
+        _putd( _get_proctime() );
+        _puts("\n");
+
+#if BOOT_DEBUG_PT
+_puts("  vaddr = ");
+_putx( _ptabs_vaddr[vspace_id] );
+_puts(" / paddr = ");
+_putl( _ptabs_paddr[vspace_id] );
+_puts(" / PT2 number = ");
+_putd( _max_pt2[vspace_id] );
+_puts("\n");
+#endif
+    }
+} // end boot_pt_init()
+
+///////////////////////////////////////////////////////////////////////////////
+// This function initializes all private vobjs defined in the vspaces,
+// such as mwmr channels, barriers and locks, because these vobjs 
+// are not known, and not initialized by the compiler.
+// The MMU is supposed to be activated...
+///////////////////////////////////////////////////////////////////////////////
+void boot_vobjs_init() 
+{
+    mapping_header_t* header = (mapping_header_t *) & seg_boot_mapping_base;
+    mapping_vspace_t* vspace = _get_vspace_base(header);
+    mapping_vobj_t* vobj     = _get_vobj_base(header);
+
+    unsigned int vspace_id;
+    unsigned int vobj_id;
+
+    // loop on the vspaces
+    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
+    {
+
+#if BOOT_DEBUG_VOBJS
+_puts("\n[BOOT DEBUG] ****** vobjs initialisation in vspace ");
+_puts(vspace[vspace_id].name);
+_puts(" ******\n");
+#endif
+
+        _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[vspace_id] >> 13) );
+
+        unsigned int ptab_found = 0;
+
+        // loop on the vobjs
+        for (vobj_id = vspace[vspace_id].vobj_offset;
+             vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs);
+             vobj_id++) 
+        {
+            switch (vobj[vobj_id].type) 
+            {
+                case VOBJ_TYPE_MWMR:    // storage capacity is (vobj.length/4 - 5) words
+                {
+                    mwmr_channel_t* mwmr = (mwmr_channel_t *) (vobj[vobj_id].vaddr);
+                    mwmr->ptw = 0;
+                    mwmr->ptr = 0;
+                    mwmr->sts = 0;
+                    mwmr->width = vobj[vobj_id].init;
+                    mwmr->depth = (vobj[vobj_id].length >> 2) - 6;
+                    mwmr->lock = 0;
+#if BOOT_DEBUG_VOBJS
+_puts("MWMR    : ");
+_puts(vobj[vobj_id].name);
+_puts(" / depth = ");
+_putd(mwmr->depth);
+_puts(" / width = ");
+_putd(mwmr->width);
+_puts("\n");
+#endif
+                    break;
+                }
+                case VOBJ_TYPE_ELF:    // initialisation done by the loader 
+                {
+#if BOOT_DEBUG_VOBJS
+_puts("ELF     : ");
+_puts(vobj[vobj_id].name);
+_puts(" / length = ");
+_putx(vobj[vobj_id].length);
+_puts("\n");
+#endif
+                    break;
+                }
+                case VOBJ_TYPE_BLOB:    // initialisation done by the loader 
+                {
+#if BOOT_DEBUG_VOBJS
+_puts("BLOB     : ");
+_puts(vobj[vobj_id].name);
+_puts(" / length = ");
+_putx(vobj[vobj_id].length);
+_puts("\n");
+#endif
+                    break;
+                }
+                case VOBJ_TYPE_BARRIER:    // init is the number of participants
+                {
+                    giet_barrier_t* barrier = (giet_barrier_t *) (vobj[vobj_id].vaddr);
+                    barrier->count = vobj[vobj_id].init;
+                    barrier->init = vobj[vobj_id].init;
+#if BOOT_DEBUG_VOBJS
+_puts("BARRIER : ");
+_puts(vobj[vobj_id].name);
+_puts(" / init_value = ");
+_putd(barrier->init);
+_puts("\n");
+#endif
+                    break;
+                }
+                case VOBJ_TYPE_LOCK:    // init value is "not taken"
+                {
+                    unsigned int* lock = (unsigned int *) (vobj[vobj_id].vaddr);
+                    *lock = 0;
+#if BOOT_DEBUG_VOBJS
+_puts("LOCK    : ");
+_puts(vobj[vobj_id].name);
+_puts("\n");
+#endif
+                    break;
+                }
+                case VOBJ_TYPE_BUFFER:    // nothing to initialise
+                {
+#if BOOT_DEBUG_VOBJS
+_puts("BUFFER  : ");
+_puts(vobj[vobj_id].name);
+_puts(" / paddr = ");
+_putl(vobj[vobj_id].paddr);
+_puts(" / length = ");
+_putx(vobj[vobj_id].length);
+_puts("\n");
+#endif
+                    break;
+                }
+                case VOBJ_TYPE_MEMSPACE:
+                {
+                    giet_memspace_t* memspace = (giet_memspace_t *) vobj[vobj_id].vaddr;
+                    memspace->buffer = (void *) vobj[vobj_id].vaddr + 8;
+                    memspace->size = vobj[vobj_id].length - 8;
+#if BOOT_DEBUG_VOBJS
+_puts("MEMSPACE  : ");
+_puts(vobj[vobj_id].name);
+_puts(" / vaddr = ");
+_putx(vobj[vobj_id].vaddr);
+_puts(" / length = ");
+_putx(vobj[vobj_id].length);
+_puts(" / buffer = ");
+_putx((unsigned int)memspace->buffer);
+_puts(" / size = ");
+_putx(memspace->size);
+_puts("\n");
+#endif
+                    break;
+                }
+                case VOBJ_TYPE_PTAB:    // nothing to initialize
+                {
+                    ptab_found = 1;
+#if BOOT_DEBUG_VOBJS
+_puts("PTAB    : ");
+_puts(vobj[vobj_id].name);
+_puts(" / length = ");
+_putx(vobj[vobj_id].length);
+_puts("\n");
+#endif
+                    break;
+                }
+                case VOBJ_TYPE_CONST:
+                {
+                    unsigned int* addr = (unsigned int *) vobj[vobj_id].vaddr;
+                    *addr = vobj[vobj_id].init;
+#if BOOT_DEBUG_VOBJS
+_puts("CONST   : ");
+_puts(vobj[vobj_id].name);
+_puts(" / Paddr :");
+_putl(vobj[vobj_id].paddr);
+_puts(" / init = ");
+_putx(*addr);
+_puts("\n");
+#endif
+                    break;
+                }
+                default:
+                {
+                    _puts("\n[BOOT ERROR] illegal vobj type: ");
+                    _putd(vobj[vobj_id].type);
+                    _puts("\n");
+                    _exit();
+                }
+            }            // end switch type
+        }            // end loop on vobjs
+        if (ptab_found == 0) 
+        {
+            _puts("\n[BOOT ERROR] Missing PTAB for vspace ");
+            _putd(vspace_id);
+            _exit();
+        }
+    } // end loop on vspaces
+
+} // end boot_vobjs_init()
+
+///////////////////////////////////////////////////////////////////////////////
+// This function returns in the vbase and length buffers the virtual base 
+// address and the length of the  segment allocated to the schedulers array 
+// in the cluster defined by the clusterid argument.
+///////////////////////////////////////////////////////////////////////////////
+void boot_get_sched_vaddr( unsigned int  cluster_id,
+                           unsigned int* vbase, 
+                           unsigned int* length )
+{
+    mapping_header_t* header = (mapping_header_t *) & seg_boot_mapping_base;
+    mapping_vobj_t*   vobj   = _get_vobj_base(header);
+    mapping_vseg_t*   vseg   = _get_vseg_base(header);
+    mapping_pseg_t*   pseg   = _get_pseg_base(header);
+
+    unsigned int vseg_id;
+    unsigned int found = 0;
+
+    for ( vseg_id = 0 ; (vseg_id < header->vsegs) && (found == 0) ; vseg_id++ )
+    {
+        if ( (vobj[vseg[vseg_id].vobj_offset].type == VOBJ_TYPE_SCHED) && 
+             (pseg[vseg[vseg_id].psegid].clusterid == cluster_id ) )
+        {
+            *vbase  = vseg[vseg_id].vbase;
+            *length = vobj[vseg[vseg_id].vobj_offset].length;
+            found = 1;
+        }
+    }
+    if ( found == 0 )
+    {
+        mapping_cluster_t* cluster = _get_cluster_base(header);
+        _puts("\n[BOOT ERROR] No vobj of type SCHED in cluster [");
+        _putd( cluster[cluster_id].x );
+        _puts(",");
+        _putd( cluster[cluster_id].y );
+        _puts("]\n");
+        _exit();
+    }
+} // end boot_get_sched_vaddr()
+
+////////////////////////////////////////////////////////////////////////////////////
+// This function initialises all processors schedulers.
+// This is done by processor 0, and the MMU must be activated.
+// - In Step 1, it initialises the _schedulers[gpid] pointers array, and scan
+//              the processors to initialise the schedulers, including the
+//              idle_task context (ltid == 14).
+// - In Step 2, it scan all tasks in all vspaces to initialise the tasks contexts, 
+//              as specified in the mapping_info data structure. 
+////////////////////////////////////////////////////////////////////////////////////
+void boot_schedulers_init() 
+{
+    mapping_header_t*  header  = (mapping_header_t *) & seg_boot_mapping_base;
+    mapping_cluster_t* cluster = _get_cluster_base(header);
+    mapping_vspace_t*  vspace  = _get_vspace_base(header);
+    mapping_task_t*    task    = _get_task_base(header);
+    mapping_vobj_t*    vobj    = _get_vobj_base(header);
+    mapping_proc_t*    proc    = _get_proc_base(header);
+    mapping_irq_t*     irq     = _get_irq_base(header);
+
+    unsigned int cluster_id;    // cluster index in mapping_info 
+    unsigned int proc_id;       // processor index in mapping_info 
+    unsigned int irq_id;        // irq index in mapping_info
+    unsigned int vspace_id;     // vspace index in mapping_info
+    unsigned int task_id;       // task index in mapping_info
+
+    // TTY, NIC, CMA, HBA, TIM and DMA channels allocators 
+    // - TTY[0] is reserved for the kernel
+    // - In all clusters the first NB_PROCS_MAX timers 
+    //   are reserved for the kernel (context switch)
+
+    unsigned int alloc_tty_channel = 0;            // TTY channel allocator
+    unsigned int alloc_nic_channel = 0;            // NIC channel allocator
+    unsigned int alloc_cma_channel = 0;            // CMA channel allocator
+    unsigned int alloc_hba_channel = 0;            // IOC channel allocator
+    unsigned int alloc_tim_channel[X_SIZE*Y_SIZE]; // user TIMER allocators
+
+    if (!GIET_MONO_TTY) alloc_tty_channel++;
+
+    /////////////////////////////////////////////////////////////////////////
+    // Step 1 : loop on the clusters and on the processors 
+    //          to initialize the schedulers[] array of pointers,
+    //          and the interrupt vectors.
+    // Implementation note:
+    // We need to use both proc_id to scan the mapping info structure,
+    // and lpid to access the schedulers array.
+    // - the _schedulers[] array of pointers can contain "holes", because
+    //   it is indexed by the global pid = cluster_xy*NB_PROCS_MAX + lpid
+    // - the mapping info array of processors is contiguous, it is indexed 
+    //   by proc_id, and use an offset specific in each cluster.
+
+    for (cluster_id = 0 ; cluster_id < X_SIZE*Y_SIZE ; cluster_id++) 
+    {
+        unsigned int x          = cluster[cluster_id].x;
+        unsigned int y          = cluster[cluster_id].y;
+        unsigned int cluster_xy = (x<<Y_WIDTH) + y;
+
+#if BOOT_DEBUG_SCHED
+_puts("\n[BOOT DEBUG] Initialise schedulers in cluster[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts("]\n");
+#endif
+        alloc_tim_channel[cluster_id] = NB_PROCS_MAX;
+
+        unsigned int  lpid;          // processor local index in cluster
+        unsigned int  sched_vbase;   // schedulers segment virtual base address
+        unsigned int  sched_length;  // schedulers segment length
+        unsigned int  nprocs;        // number of processors in cluster
+
+        nprocs = cluster[cluster_id].procs;
+
+        // checking processors number
+        if ( nprocs > NB_PROCS_MAX )
+        {
+            _puts("\n[BOOT ERROR] Too much processors in cluster[");
+            _putd( x );
+            _puts(",");
+            _putd( y );
+            _puts("]\n");
+            _exit();
+        }
+ 
+        // get scheduler array virtual base address and length
+        boot_get_sched_vaddr( cluster_id, &sched_vbase, &sched_length );
+
+        // each processor scheduler requires 4 Kbytes
+        if ( sched_length < (nprocs<<12) ) 
+        {
+            _puts("\n[BOOT ERROR] Schedulers segment too small in cluster[");
+            _putd( x );
+            _puts(",");
+            _putd( y );
+            _puts("]\n");
+            _exit();
+        }
+
+        // loop on processors
+        for ( proc_id = cluster[cluster_id].proc_offset, lpid = 0 ;
+              proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs;
+              proc_id++, lpid++ ) 
+        {
+            // current processor scheduler pointer : psched
+            static_scheduler_t* psched = (static_scheduler_t*)(sched_vbase+(lpid<<12));
+
+            // set the schedulers pointers array
+            _schedulers[cluster_xy * NB_PROCS_MAX + lpid] = psched;
+
+#if BOOT_DEBUG_SCHED
+_puts("\nProc_");
+_putd( x );
+_puts("_");
+_putd( y );
+_puts("_");
+_putd( lpid );
+_puts(" : scheduler virtual base address = ");
+_putx( sched_vbase + (lpid<<12) );
+_puts("\n");
+#endif
+
+            // initialise the "tasks" variable : default value is 0 
+            psched->tasks = 0;
+
+            // initialise the "current" variable : default value is idle_task
+            psched->current = IDLE_TASK_INDEX;
+
+            // initialise interrupt_vector with default value (valid bit = 0)
+            unsigned int slot;
+            for (slot = 0; slot < 32; slot++) psched->interrupt_vector[slot] = 0;
+
+            // initialise interrupt vector with the IRQs actually allocated
+            for (irq_id = proc[proc_id].irq_offset;
+                 irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs;
+                 irq_id++) 
+            {
+                unsigned int type    = irq[irq_id].type;
+                unsigned int icu_id  = irq[irq_id].icuid;
+                unsigned int isr_id  = irq[irq_id].isr;
+                unsigned int channel = irq[irq_id].channel;
+
+                unsigned int value = ((isr_id  & 0xFF)        ) | 
+                                     ((type    & 0xFF)   <<  8) | 
+                                     ((channel & 0x7FFF) << 16) | 
+                                     0x80000000;                    // Valid entry
+
+                psched->interrupt_vector[icu_id] = value;
+
+#if BOOT_DEBUG_SCHED
+_puts("- IRQ : icu = ");
+_putd(icu_id);
+_puts(" / type = ");
+_putd(type);
+_puts(" / isr = ");
+_putd(isr_id);
+_puts(" / channel = ");
+_putd(channel);
+_puts(" => vector_entry = ");
+_putx( value );
+_puts("\n");
+#endif
+            }
+
+            // initializes the idle_task context in scheduler:
+            // - the SR slot is 0xFF03 because this task run in kernel mode.
+            // - it uses the page table of vspace[0]
+            // - it uses the kernel TTY terminal
+            // - slots containing addresses (SP, RA, EPC, PTAB, PTPR)
+            //   must be re-initialised by kernel_parallel_init()
+
+            psched->context[IDLE_TASK_INDEX][CTX_SR_ID]    = 0xFF03;
+            psched->context[IDLE_TASK_INDEX][CTX_PTPR_ID]  = _ptabs_paddr[0]>>13;
+            psched->context[IDLE_TASK_INDEX][CTX_PTAB_ID]  = _ptabs_vaddr[0];
+            psched->context[IDLE_TASK_INDEX][CTX_TTY_ID]   = 0;
+            psched->context[IDLE_TASK_INDEX][CTX_LTID_ID]  = IDLE_TASK_INDEX;
+            psched->context[IDLE_TASK_INDEX][CTX_VSID_ID]  = 0;
+            psched->context[IDLE_TASK_INDEX][CTX_RUN_ID]   = 1;
+
+        } // end for procs
+    } // end for clusters
+
+    ///////////////////////////////////////////////////////////////////
+    // Step 2 : loop on the vspaces and the tasks 
+    //          to initialise the schedulers and the task contexts.
+
+    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
+    {
+        // We must set the PTPR depending on the vspace, because the start_vector 
+        // and the stack address are defined in virtual space.
+        _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[vspace_id] >> 13) );
+
+        // loop on the tasks in vspace (task_id is the global index)
+        for (task_id = vspace[vspace_id].task_offset;
+             task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
+             task_id++) 
+        {
+
+            // compute the cluster coordinates
+            unsigned int x          = cluster[task[task_id].clusterid].x;
+            unsigned int y          = cluster[task[task_id].clusterid].y;
+            unsigned int cluster_xy = (x<<Y_WIDTH) + y;
+
+#if BOOT_DEBUG_SCHED
+_puts("\n[BOOT DEBUG] Initialise context for task ");
+_puts( task[task_id].name );
+_puts(" in vspace ");
+_puts( vspace[vspace_id].name );
+_puts(" running on cluster[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts("]\n");
+#endif
+            // compute gpid (global processor index) and scheduler base address
+            unsigned int gpid = cluster_xy * NB_PROCS_MAX + task[task_id].proclocid;
+            static_scheduler_t* psched = _schedulers[gpid];
+
+            // ctx_sr : value required before an eret instruction
+            unsigned int ctx_sr = 0x0000FF13;
+
+            // ctx_ptpr : page table physical base address (shifted by 13 bit)
+            unsigned int ctx_ptpr = (unsigned int)(_ptabs_paddr[vspace_id] >> 13);
+
+            // ctx_ptab : page_table virtual base address
+            unsigned int ctx_ptab = _ptabs_vaddr[vspace_id];
+
+            // ctx_tty : TTY terminal global index provided by the global allocator
+            unsigned int ctx_tty = 0xFFFFFFFF;
+            if (task[task_id].use_tty) 
+            {
+                if (alloc_tty_channel >= NB_TTY_CHANNELS) 
+                {
+                    _puts("\n[BOOT ERROR] TTY index too large for task ");
+                    _puts(task[task_id].name);
+                    _puts(" in vspace ");
+                    _puts(vspace[vspace_id].name);
+                    _puts("\n");
+                    _exit();
+                }
+                ctx_tty = alloc_tty_channel;
+                if (!GIET_MONO_TTY) alloc_tty_channel++;
+            }
+            // ctx_nic : NIC channel global index provided by the global allocator
+            unsigned int ctx_nic = 0xFFFFFFFF;
+            if (task[task_id].use_nic) 
+            {
+                if (alloc_nic_channel >= NB_NIC_CHANNELS) 
+                {
+                    _puts("\n[BOOT ERROR] NIC channel index too large for task ");
+                    _puts(task[task_id].name);
+                    _puts(" in vspace ");
+                    _puts(vspace[vspace_id].name);
+                    _puts("\n");
+                    _exit();
+                }
+                ctx_nic = alloc_nic_channel;
+                alloc_nic_channel++;
+            }
+            // ctx_cma : CMA channel global index provided by the global allocator
+            unsigned int ctx_cma = 0xFFFFFFFF;
+            if (task[task_id].use_cma) 
+            {
+                if (alloc_cma_channel >= NB_CMA_CHANNELS) 
+                {
+                    _puts("\n[BOOT ERROR] CMA channel index too large for task ");
+                    _puts(task[task_id].name);
+                    _puts(" in vspace ");
+                    _puts(vspace[vspace_id].name);
+                    _puts("\n");
+                    _exit();
+                }
+                ctx_cma = alloc_cma_channel;
+                alloc_cma_channel++;
+            }
+            // ctx_hba : HBA channel global index provided by the global allocator
+            unsigned int ctx_hba = 0xFFFFFFFF;
+            if (task[task_id].use_hba) 
+            {
+                if (alloc_hba_channel >= NB_HBA_CHANNELS) 
+                {
+                    _puts("\n[BOOT ERROR] IOC channel index too large for task ");
+                    _puts(task[task_id].name);
+                    _puts(" in vspace ");
+                    _puts(vspace[vspace_id].name);
+                    _puts("\n");
+                    _exit();
+                }
+                ctx_hba = alloc_hba_channel;
+                alloc_hba_channel++;
+            }
+            // ctx_tim : TIM local channel index provided by the cluster allocator 
+            unsigned int ctx_tim = 0xFFFFFFFF;
+            if (task[task_id].use_tim) 
+            {
+                unsigned int cluster_id = task[task_id].clusterid;
+
+                if ( alloc_tim_channel[cluster_id] >= NB_TIM_CHANNELS ) 
+                {
+                    _puts("\n[BOOT ERROR] local TIMER index too large for task ");
+                    _puts(task[task_id].name);
+                    _puts(" in vspace ");
+                    _puts(vspace[vspace_id].name);
+                    _puts("\n");
+                    _exit();
+                }
+
+                // checking that there is an ISR_TIMER installed
+                unsigned int found = 0;
+                for ( irq_id = 0 ; irq_id < 32 ; irq_id++ )  
+                {
+                    unsigned int entry   = psched->interrupt_vector[irq_id];
+                    unsigned int isr     = entry & 0x000000FF;
+                    unsigned int channel = entry>>16;
+                    if ( (isr == ISR_TIMER) && (channel == alloc_tim_channel[cluster_id]) ) 
+                    {
+                        found     = 1;
+                        ctx_tim =  alloc_tim_channel[cluster_id];
+                        alloc_tim_channel[cluster_id]++;
+                        break;
+                    }
+                }
+                if (!found) 
+                {
+                    _puts("\n[BOOT ERROR] No ISR_TIMER installed for task ");
+                    _puts(task[task_id].name);
+                    _puts(" in vspace ");
+                    _puts(vspace[vspace_id].name);
+                    _puts("\n");
+                    _exit();
+                }
+            }
+            // ctx_epc : Get the virtual address of the memory location containing
+            // the task entry point : the start_vector is stored by GCC in the seg_data 
+            // segment and we must wait the .elf loading to get the entry point value...
+            mapping_vobj_t* pvobj = &vobj[vspace[vspace_id].vobj_offset + 
+                                     vspace[vspace_id].start_offset];
+            unsigned int ctx_epc = pvobj->vaddr + (task[task_id].startid)*4;
+
+            // ctx_sp :  Get the vobj containing the stack 
+            unsigned int vobj_id = task[task_id].stack_vobjid + vspace[vspace_id].vobj_offset;
+            unsigned int ctx_sp = vobj[vobj_id].vaddr + vobj[vobj_id].length;
+
+            // get local task index in scheduler
+            unsigned int ltid = psched->tasks;
+
+            // get vspace thread index
+            unsigned int thread_id = task[task_id].trdid;
+
+            if (ltid >= IDLE_TASK_INDEX) 
+            {
+                _puts("\n[BOOT ERROR] in boot_schedulers_init() : ");
+                _putd( ltid );
+                _puts(" tasks allocated to processor ");
+                _putd( gpid );
+                _puts(" / max is ");
+                _putd( IDLE_TASK_INDEX );
+                _puts("\n");
+                _exit();
+            }
+
+            // update the "tasks" and "current" fields in scheduler:
+            // the first task to execute is task 0 as soon as there is at least
+            // one task allocated to processor. 
+            psched->tasks   = ltid + 1;
+            psched->current = 0;
+
+            // initializes the task context in scheduler
+            psched->context[ltid][CTX_SR_ID]    = ctx_sr;
+            psched->context[ltid][CTX_SP_ID]    = ctx_sp;
+            psched->context[ltid][CTX_EPC_ID]   = ctx_epc;
+            psched->context[ltid][CTX_PTPR_ID]  = ctx_ptpr;
+            psched->context[ltid][CTX_TTY_ID]   = ctx_tty;
+            psched->context[ltid][CTX_CMA_ID]   = ctx_cma;
+            psched->context[ltid][CTX_HBA_ID]   = ctx_hba;
+            psched->context[ltid][CTX_NIC_ID]   = ctx_nic;
+            psched->context[ltid][CTX_TIM_ID]   = ctx_tim;
+            psched->context[ltid][CTX_PTAB_ID]  = ctx_ptab;
+            psched->context[ltid][CTX_LTID_ID]  = ltid;
+            psched->context[ltid][CTX_GTID_ID]  = task_id;
+            psched->context[ltid][CTX_TRDID_ID] = thread_id;
+            psched->context[ltid][CTX_VSID_ID]  = vspace_id;
+            psched->context[ltid][CTX_RUN_ID]   = 1;
+
+#if BOOT_DEBUG_SCHED
+_puts("\nTask ");
+_putd( task_id );
+_puts(" allocated to processor ");
+_putd( gpid );
+_puts("\n  - ctx[LTID]   = ");
+_putd( psched->context[ltid][CTX_LTID_ID] );
+_puts("\n  - ctx[SR]     = ");
+_putx( psched->context[ltid][CTX_SR_ID] );
+_puts("\n  - ctx[SP]     = ");
+_putx( psched->context[ltid][CTX_SP_ID] );
+_puts("\n  - ctx[EPC]    = ");
+_putx( psched->context[ltid][CTX_EPC_ID] );
+_puts("\n  - ctx[PTPR]   = ");
+_putx( psched->context[ltid][CTX_PTPR_ID] );
+_puts("\n  - ctx[TTY]    = ");
+_putd( psched->context[ltid][CTX_TTY_ID] );
+_puts("\n  - ctx[NIC]    = ");
+_putd( psched->context[ltid][CTX_NIC_ID] );
+_puts("\n  - ctx[CMA]    = ");
+_putd( psched->context[ltid][CTX_CMA_ID] );
+_puts("\n  - ctx[IOC]    = ");
+_putd( psched->context[ltid][CTX_HBA_ID] );
+_puts("\n  - ctx[TIM]    = ");
+_putd( psched->context[ltid][CTX_TIM_ID] );
+_puts("\n  - ctx[PTAB]   = ");
+_putx( psched->context[ltid][CTX_PTAB_ID] );
+_puts("\n  - ctx[GTID]   = ");
+_putd( psched->context[ltid][CTX_GTID_ID] );
+_puts("\n  - ctx[VSID]   = ");
+_putd( psched->context[ltid][CTX_VSID_ID] );
+_puts("\n  - ctx[TRDID]  = ");
+_putd( psched->context[ltid][CTX_TRDID_ID] );
+_puts("\n");
+#endif
+
+        } // end loop on tasks
+    } // end loop on vspaces
+} // end _schedulers_init()
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function loads the map.bin file from block device.
+// The fat global varible is defined in fat32.c file.
+//////////////////////////////////////////////////////////////////////////////////
+void boot_mapping_init()
+{
+    _ioc_init( 0 );
+
+    int fd_id = _fat_open( IOC_BOOT_PA_MODE,
+                           "map.bin",
+                           0 );         // no creation
+
+    if ( fd_id == -1 )
+    {
+        _puts("\n[BOOT ERROR] : map.bin file not found \n");
+        _exit();
+    }
+
+#if BOOT_DEBUG_MAPPING
+_puts("\n[BOOT] map.bin file successfully open at cycle ");
+_putd(_get_proctime());
+_puts("\n");
+#endif
+
+    unsigned int size    = fat.fd[fd_id].file_size;
+    unsigned int nblocks = size >> 9;
+    unsigned int offset  = size & 0x1FF;
+    if ( offset ) nblocks++;
+
+    unsigned int ok = _fat_read( IOC_BOOT_PA_MODE,
+                                 fd_id, 
+                                 (unsigned int*)( &seg_boot_mapping_base), 
+                                 nblocks,       
+                                 0 );      // offset
+    if ( ok == -1 )
+    {
+        _puts("\n[BOOT ERROR] : unable to load map.bin file \n");
+        _exit();
+    }
+    _fat_close( fd_id );
+    
+    boot_mapping_check();
+} // end boot_mapping_init()
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function open the .elf file identified by the "pathname" argument.
+// It loads the complete file in a dedicated buffer, it copies all loadable 
+// segments  at the memory virtual address defined in the .elf file, 
+// and close the file.
+// Notes: 
+// - The processor PTPR should contain the value corresponding to the
+//   vspace containing the .elf file.
+// - As this function requires a temporary memory buffer
+//   to load the complete .elf file before to copy the various segments
+//   to te proper location, it uses the seg_boot_buffer defined in map.xml.
+//////////////////////////////////////////////////////////////////////////////////
+void load_one_elf_file( unsigned int mode,
+                        char*        pathname,
+                        unsigned int vspace_id )    // to use the proper page_table
+{
+    unsigned int seg_id;
+
+    // get boot buffer address and size
+    char*             boot_buffer      = (char*)(&seg_boot_buffer_base);
+    unsigned int      boot_buffer_size = (unsigned int)(&seg_boot_buffer_size);
+
+#if BOOT_DEBUG_ELF
+_puts("\n[BOOT DEBUG] Start searching file ");
+_puts( pathname );
+_puts(" at cycle ");
+_putd( _get_proctime() );
+_puts("\n");
+#endif
+
+    // open .elf file
+    int fd_id = _fat_open( mode,
+                           pathname,
+                           0 );      // no creation
+    if ( fd_id < 0 )
+    {
+        _puts("\n[BOOT ERROR] load_one_elf_file() : ");
+        _puts( pathname );
+        _puts(" not found\n");
+        _exit();
+    }
+
+    // check boot_buffer size versus file size
+    if ( fat.fd[fd_id].file_size > boot_buffer_size )
+    {
+        _puts("\n[BOOT ERROR] load_one_elf_file() : ");
+        _puts( pathname );
+        _puts(" exceeds the seg_boot_buffer size\n");
+        _exit();
+    }
+
+    // compute number of sectors
+    unsigned int nbytes   = fat.fd[fd_id].file_size;
+    unsigned int nsectors = nbytes>>9;
+    if( nbytes & 0x1FF) nsectors++;
+
+    // load file in boot_buffer
+    if( _fat_read( mode, 
+                   fd_id, 
+                   boot_buffer,
+                   nsectors,
+                   0 ) != nsectors )
+    {
+        _puts("\n[BOOT ERROR] load_one_elf_file() : unexpected EOF for file ");
+        _puts( pathname );
+        _puts("\n");   
+        _exit();
+    }
+
+    // Check ELF Magic Number in ELF header
+    Elf32_Ehdr* elf_header_ptr = (Elf32_Ehdr*)boot_buffer;
+
+    if ( (elf_header_ptr->e_ident[EI_MAG0] != ELFMAG0) ||
+         (elf_header_ptr->e_ident[EI_MAG1] != ELFMAG1) ||
+         (elf_header_ptr->e_ident[EI_MAG2] != ELFMAG2) ||
+         (elf_header_ptr->e_ident[EI_MAG3] != ELFMAG3) )
+    {
+        _puts("\n[BOOT ERROR] load_elf() : file ");
+        _puts( pathname );
+        _puts(" does not use ELF format\n");   
+        _exit();
+    }
+
+    // get program header table pointer
+    unsigned int pht_index = elf_header_ptr->e_phoff;
+    if( pht_index == 0 )
+    {
+        _puts("\n[BOOT ERROR] load_one_elf_file() : file ");
+        _puts( pathname );
+        _puts(" does not contain loadable segment\n");   
+        _exit();
+    }
+    Elf32_Phdr* elf_pht_ptr = (Elf32_Phdr*)(boot_buffer + pht_index);
+
+    // get number of segments
+    unsigned int nsegments   = elf_header_ptr->e_phnum;
+
+#if BOOT_DEBUG_ELF
+_puts("\n[BOOT DEBUG] File ");
+_puts( pathname );
+_puts(" loaded at cycle ");
+_putd( _get_proctime() );
+_puts(" / bytes = ");
+_putd( nbytes );
+_puts(" / sectors = ");
+_putd( nsectors );
+_puts("\n");
+#endif
+
+    // Loop on loadable segments in the ELF file
+    for (seg_id = 0 ; seg_id < nsegments ; seg_id++)
+    {
+        if(elf_pht_ptr[seg_id].p_type == PT_LOAD)
+        {
+            // Get segment attributes
+            unsigned int seg_vaddr  = elf_pht_ptr[seg_id].p_vaddr;
+            unsigned int seg_offset = elf_pht_ptr[seg_id].p_offset;
+            unsigned int seg_filesz = elf_pht_ptr[seg_id].p_filesz;
+            unsigned int seg_memsz  = elf_pht_ptr[seg_id].p_memsz;
+
+            if( seg_memsz < seg_filesz )
+            {
+                _puts("\n[BOOT ERROR] load_one_elf_file() : segment at vaddr = ");
+                _putx( seg_vaddr );
+                _puts(" in file ");
+                _puts( pathname );
+                _puts(" has a wrong size \n");   
+                _exit();
+            }
+
+            // fill empty space with 0 as required
+            if( seg_memsz > seg_filesz )
+            {
+                unsigned int i; 
+                for( i = seg_filesz ; i < seg_memsz; i++ ) boot_buffer[i] = 0;
+            } 
+
+            unsigned int src_vaddr = (unsigned int)boot_buffer + seg_offset;
+
+#if BOOT_DEBUG_ELF
+_puts(" - segment ");
+_putd( seg_id );
+_puts(" / dst_vaddr = ");
+_putx( seg_vaddr );
+_puts(" / src_vaddr = ");
+_putx( src_vaddr );
+_puts(" / size = ");
+_putx( seg_filesz );
+_puts("\n");
+#endif
+
+            // copy the segment from boot buffer to destination buffer
+            if( NB_DMA_CHANNELS > 0 )
+            {
+                _dma_copy( vspace_id,           // required for V2P translation
+                           (char*)seg_vaddr,
+                           (char*)src_vaddr,
+                           seg_filesz );
+            }
+            else
+            {
+                _memcpy( (char*)seg_vaddr,
+                         (char*)src_vaddr,
+                         seg_filesz );
+            }
+        }
+    } // end for segments
+
+    // close .elf file
+    _fat_close( fd_id );
+
+} // end load_one_elf_file()
+
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function uses the map.bin data structure to load the "kernel.elf" file
+// as well as the various "application.elf" files.
+// The "preloader.elf" file is not loaded, because it has been burned in the ROM.
+// The "boot.elf" file is not loaded, because it has been loaded by the preloader.
+// It scans all vobjs defined in the map.bin data structure to collect
+// all .elf files pathnames, and calls the load_one_elf_file() function to
+// load all loadable segments at the virtual address found in the .elf file.
+//////////////////////////////////////////////////////////////////////////////////
+void boot_elf_load()
+{
+    mapping_header_t* header = (mapping_header_t *) & seg_boot_mapping_base;
+    mapping_vspace_t* vspace = _get_vspace_base( header );
+    mapping_vobj_t*   vobj   = _get_vobj_base( header );
+    unsigned int      vspace_id;
+    unsigned int      vobj_id;
+    unsigned int      found;
+
+    // Scan all vobjs corresponding to global vsegs,
+    // to find the pathname to the kernel.elf file
+    found = 0;
+    for( vobj_id = 0 ; vobj_id < header->globals ; vobj_id++ )
+    {
+        if(vobj[vobj_id].type == VOBJ_TYPE_ELF) 
+        {   
+            found = 1;
+            break;
+        }
+    }
+
+    // We need one kernel.elf file
+    if (found == 0)
+    {
+        _puts("[BOOT ERROR] boot_elf_load() : kernel.elf file not found\n");
+        _exit();
+    }
+
+    load_one_elf_file( IOC_BOOT_VA_MODE,
+                       vobj[vobj_id].binpath,
+                       0 );                         // vspace 0
+
+    _puts("\n[BOOT] File ");
+    _puts( vobj[vobj_id].binpath );
+    _puts(" loaded at cycle ");
+    _putd( _get_proctime() );
+    _puts("\n");
+
+    // loop on the vspaces, scanning all vobjs in a vspace,
+    // to find the pathname of the .elf file associated to the vspace.
+    for( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
+    {
+        // Set PTPR depending on the vspace, as seg_data is defined in virtual space.
+        _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[vspace_id] >> 13) );
+
+        // loop on the vobjs in vspace (vobj_id is the global index)
+        unsigned int found = 0;
+        for (vobj_id = vspace[vspace_id].vobj_offset;
+             vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs);
+             vobj_id++) 
+        {
+            if(vobj[vobj_id].type == VOBJ_TYPE_ELF) 
+            {   
+                found = 1;
+                break;
+            }
+        }
+
+        // We want one .elf file per vspace
+        if (found == 0)
+        {
+            _puts("[BOOT ERROR] boot_elf_load() : .elf file not found for vspace ");
+            _puts( vspace[vspace_id].name );
+            _puts("\n");
+            _exit();
+        }
+
+        load_one_elf_file( IOC_BOOT_VA_MODE,
+                           vobj[vobj_id].binpath,
+                           vspace_id );
+
+        _puts("\n[BOOT] File ");
+        _puts( vobj[vobj_id].binpath );
+        _puts(" loaded at cycle ");
+        _putd( _get_proctime() );
+        _puts("\n");
+
+    }  // end for vspaces
+
+    // restaure vspace 0 PTPR
+    _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[0] >> 13) );
+
+} // end boot_elf_load()
+
+////////////////////////////////////////////////////////////////////////////////
+// This function intializes the periherals and coprocessors, as specified
+// in the mapping_info file.
+////////////////////////////////////////////////////////////////////////////////
+void boot_peripherals_init() 
+{
+    mapping_header_t * header   = (mapping_header_t *) & seg_boot_mapping_base;
+    mapping_cluster_t * cluster = _get_cluster_base(header);
+    mapping_periph_t * periph   = _get_periph_base(header);
+    mapping_vobj_t * vobj       = _get_vobj_base(header);
+    mapping_vspace_t * vspace   = _get_vspace_base(header);
+    mapping_coproc_t * coproc   = _get_coproc_base(header);
+    mapping_cp_port_t * cp_port = _get_cp_port_base(header);
+
+    unsigned int cluster_id;
+    unsigned int periph_id;
+    unsigned int coproc_id;
+    unsigned int cp_port_id;
+    unsigned int channel_id;
+
+    // loop on all physical clusters
+    for (cluster_id = 0; cluster_id < X_SIZE*Y_SIZE; cluster_id++) 
+    {
+        // computes cluster coordinates
+        unsigned int x          = cluster[cluster_id].x;
+        unsigned int y          = cluster[cluster_id].y;
+        unsigned int cluster_xy = (x<<Y_WIDTH) + y;
+
+#if BOOT_DEBUG_PERI
+_puts("\n[BOOT DEBUG] ****** peripherals initialisation in cluster[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts("] ******\n");
+#endif
+
+        // loop on peripherals
+        for (periph_id = cluster[cluster_id].periph_offset;
+             periph_id < cluster[cluster_id].periph_offset +
+             cluster[cluster_id].periphs; periph_id++) 
+        {
+            unsigned int type       = periph[periph_id].type;
+            unsigned int channels   = periph[periph_id].channels;
+
+            switch (type) 
+            {
+                case PERIPH_TYPE_IOC:    // vci_block_device component
+                {
+                    // initialize all channels except channel 0 because it has been
+                    // initialize during mapping_info loading
+                    for (channel_id = 1; channel_id < channels; channel_id++) 
+                    {
+                        _ioc_init( channel_id );
+                    }
+#if BOOT_DEBUG_PERI
+_puts("- IOC / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_DMA:    // vci_multi_dma component
+                {
+                    for (channel_id = 0; channel_id < channels; channel_id++) 
+                    {
+                        _dma_init( cluster_xy, channel_id );
+                    }
+#if BOOT_DEBUG_PERI
+_puts("- DMA / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_FBF:    // vci_block_device component
+                {
+                    // nothing to do
+#if BOOT_DEBUG_PERI
+_puts("- FBF / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_CMA:    // vci_chbuf_dma component
+                {
+                    for (channel_id = 0; channel_id < channels; channel_id++) 
+                    {
+                        // TODO
+                    }
+#if BOOT_DEBUG_PERI
+_puts("- CMA / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_NIC:    // vci_multi_nic component
+                {
+                    for (channel_id = 0; channel_id < channels; channel_id++) 
+                    {
+                        // TODO
+                    }
+#if BOOT_DEBUG_PERI
+_puts("- NIC / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_XCU:    // vci_xicu component
+                {
+                    // nothing to do 
+#if BOOT_DEBUG_PERI
+_puts("- XCU / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_MMC:    // vci_memcache config
+                {
+                    // nothing to do
+#if BOOT_DEBUG_PERI
+_puts("- MMC / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_TTY:    // vci_multi_tty component
+                {
+#if BOOT_DEBUG_PERI
+_puts("- TTY / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+                case PERIPH_TYPE_IOB:    // vci_io_bridge component
+                {
+                    if (USE_IOB) 
+                    {
+                        // TODO
+                        // get the iommu page table physical address
+                        // define IPI address mapping the IOC interrupt 
+                        // set IOMMU page table address
+                        // pseg_base[IOB_IOMMU_PTPR] = ptab_pbase;    
+                        // activate IOMMU
+                        // pseg_base[IOB_IOMMU_ACTIVE] = 1;        
+                    }
+#if BOOT_DEBUG_PERI
+_puts("- IOB / channels = ");
+_putd(channels);
+_puts("\n");
+#endif
+                    break;
+                }
+            }  // end switch periph type
+        }  // end for periphs
+
+#if BOOT_DEBUG_PERI
+_puts("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster[");
+_putd( x );
+_puts(",");
+_putd( y );
+_puts("] ******\n");
+#endif
+
+        // loop on coprocessors
+        for ( coproc_id = cluster[cluster_id].coproc_offset;
+              coproc_id < cluster[cluster_id].coproc_offset +
+              cluster[cluster_id].coprocs; coproc_id++ ) 
+        {
+
+#if BOOT_DEBUG_PERI
+_puts("- coprocessor name : ");
+_puts(coproc[coproc_id].name);
+_puts(" / nb ports = ");
+_putd((unsigned int) coproc[coproc_id].ports);
+_puts("\n");
+#endif
+            // loop on the coprocessor ports
+            for ( cp_port_id = coproc[coproc_id].port_offset;
+                  cp_port_id < coproc[coproc_id].port_offset + coproc[coproc_id].ports;
+                  cp_port_id++ ) 
+            {
+                unsigned int vspace_id = cp_port[cp_port_id].vspaceid;
+                unsigned int vobj_id   = cp_port[cp_port_id].mwmr_vobjid + 
+                                                vspace[vspace_id].vobj_offset;
+
+                // Get MWMR channel base address 
+                paddr_t mwmr_channel_pbase = vobj[vobj_id].paddr;
+
+                _mwr_hw_init( cluster_xy,
+                              cp_port_id, 
+                              cp_port[cp_port_id].direction, 
+                              mwmr_channel_pbase );
+#if BOOT_DEBUG_PERI
+_puts("     port direction: ");
+_putd( (unsigned int)cp_port[cp_port_id].direction );
+_puts(" / mwmr_channel_pbase = ");
+_putl( mwmr_channel_pbase );
+_puts(" / name = ");
+_puts(vobj[vobj_id].name);
+_puts(" / in vspace ");
+_puts(vspace[vspace_id].name);
+_puts("\n"); 
+#endif
+            } // end for cp_ports
+        } // end for coprocs
+    } // end for clusters
+} // end boot_peripherals_init()
+
+/////////////////////////////////////////////////////////////////////////
+// This function is the entry point of the boot code for all processors.
+// Most of this code is executed by Processor 0 only.
+/////////////////////////////////////////////////////////////////////////
+void boot_init() 
+{
+    mapping_header_t* header     = (mapping_header_t *) & seg_boot_mapping_base;
+    unsigned int      gpid       = _get_procid();
+    unsigned int      cluster_xy = gpid / NB_PROCS_MAX;
+    unsigned int      lpid       = gpid % NB_PROCS_MAX;
+ 
+    if ( gpid == 0 )    // only Processor 0 does it
+    {
+        _puts("\n[BOOT] boot_init start at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+
+        // Loading the map.bin file into memory and checking it
+        boot_mapping_init();
+
+        _puts("\n[BOOT] Mapping ");
+        _puts( header->name );
+        _puts(" loaded at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+
+        // Building all page tables
+        boot_pt_init();
+
+        _puts("\n[BOOT] Page Tables initialisation completed at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+
+        // Activating proc 0 MMU 
+        _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[0]>>13) );
+        _set_mmu_mode( 0xF );
+
+        _puts("\n[BOOT] Processor[0,0,0] : MMU activation at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+
+        // Initialising private vobjs in vspaces
+        boot_vobjs_init();
+
+        _puts("\n[BOOT] Private vobjs initialised at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+
+        // Initializing schedulers
+        boot_schedulers_init();
+
+        _puts("\n[BOOT] All schedulers initialised at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+        
+        // Setting CP0_SCHED register for proc 0
+        _set_sched( (unsigned int)_schedulers[0] );
+
+        // Initializing peripherals
+        boot_peripherals_init();
+
+        _puts("\n[BOOT] All peripherals initialised at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+
+        // Loading all .elf files
+        boot_elf_load();
+
+        _puts("\n[BOOT] All ELF files loaded at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+
+        // P0 starts all other processors
+        unsigned int x,y,p;
+        for (x = 0 ; x < X_SIZE ; x++) 
+        {
+            for (y = 0 ; y < Y_SIZE ; y++) 
+            {
+                for(p = 0; p < NB_PROCS_MAX; p++) 
+                {
+                    if ( (x != 0) || (y != 0) || (p != 0) )
+                    {
+                        _xcu_send_ipi( (x<<Y_WIDTH) + y, 
+                                       p,
+                                       (unsigned int)boot_init );
+                    }
+                }
+            }
+        }
+    }  // end monoprocessor boot
+
+    // reset BEV bit in the status register to use GIET exception
+    // handler instead of the PRELOADER exception handler
+    _set_sr( 0 );
+
+    // all processor initialise SCHED register
+    _set_sched( (unsigned int)_schedulers[gpid] );
+
+    // all processors (but Proc 0) activate MMU
+    if ( gpid != 0 )
+    {
+        _set_mmu_ptpr( (unsigned int)(_ptabs_paddr[0]>>13) );
+        _set_mmu_mode( 0xF );
+
+        _tty_get_lock( 0 );
+        _puts("\n[BOOT] Processor[");
+        _putd( cluster_xy >> Y_WIDTH );
+        _puts(",");
+        _putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+        _puts(",");
+        _putd( lpid );
+        _puts("] : MMU activation at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+        _tty_release_lock( 0 );
+    }
+
+    // all processors jump to kernel_init
+    unsigned int kernel_entry = (unsigned int)&seg_kernel_init_base;
+
+    _tty_get_lock( 0 );
+    _puts("\n[BOOT] Processor[");
+    _putd( cluster_xy >> Y_WIDTH );
+    _puts(",");
+    _putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+    _puts(",");
+    _putd( lpid );
+    _puts("] enters kernel at cycle ");
+    _putd( _get_proctime() );
+    _puts(" / kernel entry = ");
+    _putx( kernel_entry );
+    _puts("\n");
+    _tty_release_lock( 0 );
+
+    asm volatile( "jr   %0" ::"r"(kernel_entry) );
+
+} // end boot_init()
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_boot/boot.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_boot/boot.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_boot/boot.ld	(revision 283)
@@ -0,0 +1,36 @@
+
+/****************************************************************************/
+/* Definition of the base addresses for all vsegs used by the GIET_VM       */
+/****************************************************************************/
+
+INCLUDE giet_vsegs.ld
+
+/****************************************************************************/
+/* Definition of the entry point for the BOOT code.                         */ 
+/* The address of the boot_init function is stored in the .elf header,      */
+/* and is used by the prÃ©loader to jump into the boot code.                 */
+/****************************************************************************/
+
+ENTRY(boot_init)
+
+/****************************************************************************/
+/* Grouping sections into virtual segment for boot code and data             */
+/****************************************************************************/
+SECTIONS
+{
+    . = seg_boot_code_base;
+    seg_boot_code : 
+    {
+        *(.text)
+        *(.rodata)
+        *(.rodata.*)
+    }
+
+    . = seg_boot_data_base;
+    seg_boot_data :
+    {
+        *(.bootdata)
+        *(.fatdata)
+    }
+}
+
Index: /branch/giet_vm_ioc_drivers/giet_boot/elf-types.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_boot/elf-types.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_boot/elf-types.h	(revision 283)
@@ -0,0 +1,2645 @@
+/* This file defines standard ELF types, structures, and macros.
+   Copyright (C) 1995-2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _ELF_TYPES_H
+#define	_ELF_TYPES_H
+
+/* Type for a 16-bit quantity.  */
+typedef unsigned short Elf32_Half;
+typedef unsigned short Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef unsigned int   Elf32_Word;
+typedef	int            Elf32_Sword;
+typedef unsigned int   Elf64_Word;
+typedef	int            Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef unsigned long  Elf32_Xword;
+typedef	long           Elf32_Sxword;
+typedef unsigned long  Elf64_Xword;
+typedef	long           Elf64_Sxword;
+
+/* Type of addresses.  */
+typedef unsigned int   Elf32_Addr;
+typedef unsigned long  Elf64_Addr;
+
+/* Type of file offsets.  */
+typedef unsigned int   Elf32_Off;
+typedef unsigned long  Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef unsigned short Elf32_Section;
+typedef unsigned short Elf64_Section;
+
+/* Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf32_Half	e_type;			/* Object file type */
+  Elf32_Half	e_machine;		/* Architecture */
+  Elf32_Word	e_version;		/* Object file version */
+  Elf32_Addr	e_entry;		/* Entry point virtual address */
+  Elf32_Off	e_phoff;		/* Program header table file offset */
+  Elf32_Off	e_shoff;		/* Section header table file offset */
+  Elf32_Word	e_flags;		/* Processor-specific flags */
+  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf32_Half	e_phentsize;		/* Program header table entry size */
+  Elf32_Half	e_phnum;		/* Program header table entry count */
+  Elf32_Half	e_shentsize;		/* Section header table entry size */
+  Elf32_Half	e_shnum;		/* Section header table entry count */
+  Elf32_Half	e_shstrndx;		/* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf64_Half	e_type;			/* Object file type */
+  Elf64_Half	e_machine;		/* Architecture */
+  Elf64_Word	e_version;		/* Object file version */
+  Elf64_Addr	e_entry;		/* Entry point virtual address */
+  Elf64_Off	e_phoff;		/* Program header table file offset */
+  Elf64_Off	e_shoff;		/* Section header table file offset */
+  Elf64_Word	e_flags;		/* Processor-specific flags */
+  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf64_Half	e_phentsize;		/* Program header table entry size */
+  Elf64_Half	e_phnum;		/* Program header table entry count */
+  Elf64_Half	e_shentsize;		/* Section header table entry size */
+  Elf64_Half	e_shnum;		/* Section header table entry count */
+  Elf64_Half	e_shstrndx;		/* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define ELFMAG0		0x7f		/* Magic number byte 0 */
+
+#define EI_MAG1		1		/* File identification byte 1 index */
+#define ELFMAG1		'E'		/* Magic number byte 1 */
+
+#define EI_MAG2		2		/* File identification byte 2 index */
+#define ELFMAG2		'L'		/* Magic number byte 2 */
+
+#define EI_MAG3		3		/* File identification byte 3 index */
+#define ELFMAG3		'F'		/* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word.  */
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4		/* File class byte index */
+#define ELFCLASSNONE	0		/* Invalid class */
+#define ELFCLASS32	1		/* 32-bit objects */
+#define ELFCLASS64	2		/* 64-bit objects */
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5		/* Data encoding byte index */
+#define ELFDATANONE	0		/* Invalid data encoding */
+#define ELFDATA2LSB	1		/* 2's complement, little endian */
+#define ELFDATA2MSB	2		/* 2's complement, big endian */
+#define ELFDATANUM	3
+
+#define EI_VERSION	6		/* File version byte index */
+					/* Value must be EV_CURRENT */
+
+#define EI_OSABI	7		/* OS ABI identification */
+#define ELFOSABI_NONE		0	/* UNIX System V ABI */
+#define ELFOSABI_SYSV		0	/* Alias.  */
+#define ELFOSABI_HPUX		1	/* HP-UX */
+#define ELFOSABI_NETBSD		2	/* NetBSD.  */
+#define ELFOSABI_LINUX		3	/* Linux.  */
+#define ELFOSABI_SOLARIS	6	/* Sun Solaris.  */
+#define ELFOSABI_AIX		7	/* IBM AIX.  */
+#define ELFOSABI_IRIX		8	/* SGI Irix.  */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD.  */
+#define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX.  */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto.  */
+#define ELFOSABI_OPENBSD	12	/* OpenBSD.  */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define EI_ABIVERSION	8		/* ABI version */
+
+#define EI_PAD		9		/* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type).  */
+
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* Relocatable file */
+#define ET_EXEC		2		/* Executable file */
+#define ET_DYN		3		/* Shared object file */
+#define ET_CORE		4		/* Core file */
+#define	ET_NUM		5		/* Number of defined types */
+#define ET_LOOS		0xfe00		/* OS-specific range start */
+#define ET_HIOS		0xfeff		/* OS-specific range end */
+#define ET_LOPROC	0xff00		/* Processor-specific range start */
+#define ET_HIPROC	0xffff		/* Processor-specific range end */
+
+/* Legal values for e_machine (architecture).  */
+
+#define EM_NONE		 0		/* No machine */
+#define EM_M32		 1		/* AT&T WE 32100 */
+#define EM_SPARC	 2		/* SUN SPARC */
+#define EM_386		 3		/* Intel 80386 */
+#define EM_68K		 4		/* Motorola m68k family */
+#define EM_88K		 5		/* Motorola m88k family */
+#define EM_860		 7		/* Intel 80860 */
+#define EM_MIPS		 8		/* MIPS R3000 big-endian */
+#define EM_S370		 9		/* IBM System/370 */
+#define EM_MIPS_RS3_LE	10		/* MIPS R3000 little-endian */
+
+#define EM_PARISC	15		/* HPPA */
+#define EM_VPP500	17		/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18		/* Sun's "v8plus" */
+#define EM_960		19		/* Intel 80960 */
+#define EM_PPC		20		/* PowerPC */
+#define EM_PPC64	21		/* PowerPC 64-bit */
+#define EM_S390		22		/* IBM S390 */
+
+#define EM_V800		36		/* NEC V800 series */
+#define EM_FR20		37		/* Fujitsu FR20 */
+#define EM_RH32		38		/* TRW RH-32 */
+#define EM_RCE		39		/* Motorola RCE */
+#define EM_ARM		40		/* ARM */
+#define EM_FAKE_ALPHA	41		/* Digital Alpha */
+#define EM_SH		42		/* Hitachi SH */
+#define EM_SPARCV9	43		/* SPARC v9 64-bit */
+#define EM_TRICORE	44		/* Siemens Tricore */
+#define EM_ARC		45		/* Argonaut RISC Core */
+#define EM_H8_300	46		/* Hitachi H8/300 */
+#define EM_H8_300H	47		/* Hitachi H8/300H */
+#define EM_H8S		48		/* Hitachi H8S */
+#define EM_H8_500	49		/* Hitachi H8/500 */
+#define EM_IA_64	50		/* Intel Merced */
+#define EM_MIPS_X	51		/* Stanford MIPS-X */
+#define EM_COLDFIRE	52		/* Motorola Coldfire */
+#define EM_68HC12	53		/* Motorola M68HC12 */
+#define EM_MMA		54		/* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP		55		/* Siemens PCP */
+#define EM_NCPU		56		/* Sony nCPU embeeded RISC */
+#define EM_NDR1		57		/* Denso NDR1 microprocessor */
+#define EM_STARCORE	58		/* Motorola Start*Core processor */
+#define EM_ME16		59		/* Toyota ME16 processor */
+#define EM_ST100	60		/* STMicroelectronic ST100 processor */
+#define EM_TINYJ	61		/* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64	62		/* AMD x86-64 architecture */
+#define EM_PDSP		63		/* Sony DSP Processor */
+
+#define EM_FX66		66		/* Siemens FX66 microcontroller */
+#define EM_ST9PLUS	67		/* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7		68		/* STmicroelectronics ST7 8 bit mc */
+#define EM_68HC16	69		/* Motorola MC68HC16 microcontroller */
+#define EM_68HC11	70		/* Motorola MC68HC11 microcontroller */
+#define EM_68HC08	71		/* Motorola MC68HC08 microcontroller */
+#define EM_68HC05	72		/* Motorola MC68HC05 microcontroller */
+#define EM_SVX		73		/* Silicon Graphics SVx */
+#define EM_ST19		74		/* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX		75		/* Digital VAX */
+#define EM_CRIS		76		/* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN	77		/* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH	78		/* Element 14 64-bit DSP Processor */
+#define EM_ZSP		79		/* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX		80		/* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY	81		/* Harvard University machine-independent object files */
+#define EM_PRISM	82		/* SiTera Prism */
+#define EM_AVR		83		/* Atmel AVR 8-bit microcontroller */
+#define EM_FR30		84		/* Fujitsu FR30 */
+#define EM_D10V		85		/* Mitsubishi D10V */
+#define EM_D30V		86		/* Mitsubishi D30V */
+#define EM_V850		87		/* NEC v850 */
+#define EM_M32R		88		/* Mitsubishi M32R */
+#define EM_MN10300	89		/* Matsushita MN10300 */
+#define EM_MN10200	90		/* Matsushita MN10200 */
+#define EM_PJ		91		/* picoJava */
+#define EM_OPENRISC	92		/* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5	93		/* ARC Cores Tangent-A5 */
+#define EM_XTENSA	94		/* Tensilica Xtensa Architecture */
+#define EM_NUM		95
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+#define EM_ALPHA	0x9026
+
+/* Legal values for e_version (version).  */
+
+#define EV_NONE		0		/* Invalid ELF version */
+#define EV_CURRENT	1		/* Current version */
+#define EV_NUM		2
+
+/* Section header.  */
+
+typedef struct
+{
+  Elf32_Word	sh_name;		/* Section name (string tbl index) */
+  Elf32_Word	sh_type;		/* Section type */
+  Elf32_Word	sh_flags;		/* Section flags */
+  Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf32_Off	sh_offset;		/* Section file offset */
+  Elf32_Word	sh_size;		/* Section size in bytes */
+  Elf32_Word	sh_link;		/* Link to another section */
+  Elf32_Word	sh_info;		/* Additional section information */
+  Elf32_Word	sh_addralign;		/* Section alignment */
+  Elf32_Word	sh_entsize;		/* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+  Elf64_Word	sh_name;		/* Section name (string tbl index) */
+  Elf64_Word	sh_type;		/* Section type */
+  Elf64_Xword	sh_flags;		/* Section flags */
+  Elf64_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf64_Off	sh_offset;		/* Section file offset */
+  Elf64_Xword	sh_size;		/* Section size in bytes */
+  Elf64_Word	sh_link;		/* Link to another section */
+  Elf64_Word	sh_info;		/* Additional section information */
+  Elf64_Xword	sh_addralign;		/* Section alignment */
+  Elf64_Xword	sh_entsize;		/* Entry size if section holds table */
+} Elf64_Shdr;
+
+/* Special section indices.  */
+
+#define SHN_UNDEF	0		/* Undefined section */
+#define SHN_LORESERVE	0xff00		/* Start of reserved indices */
+#define SHN_LOPROC	0xff00		/* Start of processor-specific */
+#define SHN_BEFORE	0xff00		/* Order section before all others
+					   (Solaris).  */
+#define SHN_AFTER	0xff01		/* Order section after all others
+					   (Solaris).  */
+#define SHN_HIPROC	0xff1f		/* End of processor-specific */
+#define SHN_LOOS	0xff20		/* Start of OS-specific */
+#define SHN_HIOS	0xff3f		/* End of OS-specific */
+#define SHN_ABS		0xfff1		/* Associated symbol is absolute */
+#define SHN_COMMON	0xfff2		/* Associated symbol is common */
+#define SHN_XINDEX	0xffff		/* Index is in extra table.  */
+#define SHN_HIRESERVE	0xffff		/* End of reserved indices */
+
+/* Legal values for sh_type (section type).  */
+
+#define SHT_NULL	  0		/* Section header table entry unused */
+#define SHT_PROGBITS	  1		/* Program data */
+#define SHT_SYMTAB	  2		/* Symbol table */
+#define SHT_STRTAB	  3		/* String table */
+#define SHT_RELA	  4		/* Relocation entries with addends */
+#define SHT_HASH	  5		/* Symbol hash table */
+#define SHT_DYNAMIC	  6		/* Dynamic linking information */
+#define SHT_NOTE	  7		/* Notes */
+#define SHT_NOBITS	  8		/* Program space with no data (bss) */
+#define SHT_REL		  9		/* Relocation entries, no addends */
+#define SHT_SHLIB	  10		/* Reserved */
+#define SHT_DYNSYM	  11		/* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY	  14		/* Array of constructors */
+#define SHT_FINI_ARRAY	  15		/* Array of destructors */
+#define SHT_PREINIT_ARRAY 16		/* Array of pre-constructors */
+#define SHT_GROUP	  17		/* Section group */
+#define SHT_SYMTAB_SHNDX  18		/* Extended section indeces */
+#define	SHT_NUM		  19		/* Number of defined types.  */
+#define SHT_LOOS	  0x60000000	/* Start OS-specific.  */
+#define SHT_GNU_HASH	  0x6ffffff6	/* GNU-style hash table.  */
+#define SHT_GNU_LIBLIST	  0x6ffffff7	/* Prelink library list */
+#define SHT_CHECKSUM	  0x6ffffff8	/* Checksum for DSO content.  */
+#define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd	/* Version definition section.  */
+#define SHT_GNU_verneed	  0x6ffffffe	/* Version needs section.  */
+#define SHT_GNU_versym	  0x6fffffff	/* Version symbol table.  */
+#define SHT_HISUNW	  0x6fffffff	/* Sun-specific high bound.  */
+#define SHT_HIOS	  0x6fffffff	/* End OS-specific type */
+#define SHT_LOPROC	  0x70000000	/* Start of processor-specific */
+#define SHT_HIPROC	  0x7fffffff	/* End of processor-specific */
+#define SHT_LOUSER	  0x80000000	/* Start of application-specific */
+#define SHT_HIUSER	  0x8fffffff	/* End of application-specific */
+
+/* Legal values for sh_flags (section flags).  */
+
+#define SHF_WRITE	     (1 << 0)	/* Writable */
+#define SHF_ALLOC	     (1 << 1)	/* Occupies memory during execution */
+#define SHF_EXECINSTR	     (1 << 2)	/* Executable */
+#define SHF_MERGE	     (1 << 4)	/* Might be merged */
+#define SHF_STRINGS	     (1 << 5)	/* Contains nul-terminated strings */
+#define SHF_INFO_LINK	     (1 << 6)	/* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER	     (1 << 7)	/* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8)	/* Non-standard OS specific handling
+					   required */
+#define SHF_GROUP	     (1 << 9)	/* Section is member of a group.  */
+#define SHF_TLS		     (1 << 10)	/* Section hold thread-local data.  */
+#define SHF_MASKOS	     0x0ff00000	/* OS-specific.  */
+#define SHF_MASKPROC	     0xf0000000	/* Processor-specific */
+#define SHF_ORDERED	     (1 << 30)	/* Special ordering requirement
+					   (Solaris).  */
+#define SHF_EXCLUDE	     (1 << 31)	/* Section is excluded unless
+					   referenced or allocated (Solaris).*/
+
+/* Section group handling.  */
+#define GRP_COMDAT	0x1		/* Mark group as COMDAT.  */
+
+/* Symbol table entry.  */
+
+typedef struct
+{
+  Elf32_Word	st_name;		/* Symbol name (string tbl index) */
+  Elf32_Addr	st_value;		/* Symbol value */
+  Elf32_Word	st_size;		/* Symbol size */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char	st_other;		/* Symbol visibility */
+  Elf32_Section	st_shndx;		/* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+  Elf64_Word	st_name;		/* Symbol name (string tbl index) */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char st_other;		/* Symbol visibility */
+  Elf64_Section	st_shndx;		/* Section index */
+  Elf64_Addr	st_value;		/* Symbol value */
+  Elf64_Xword	st_size;		/* Symbol size */
+} Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+
+typedef struct
+{
+  Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf32_Half si_flags;			/* Per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct
+{
+  Elf64_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf64_Half si_flags;			/* Per symbol flags */
+} Elf64_Syminfo;
+
+/* Possible values for si_boundto.  */
+#define SYMINFO_BT_SELF		0xffff	/* Symbol bound to self */
+#define SYMINFO_BT_PARENT	0xfffe	/* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE	0xff00	/* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags.  */
+#define SYMINFO_FLG_DIRECT	0x0001	/* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU	0x0002	/* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY	0x0004	/* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD	0x0008	/* Symbol bound to object to be lazy
+					   loaded */
+/* Syminfo version values.  */
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+
+#define STB_LOCAL	0		/* Local symbol */
+#define STB_GLOBAL	1		/* Global symbol */
+#define STB_WEAK	2		/* Weak symbol */
+#define	STB_NUM		3		/* Number of defined types.  */
+#define STB_LOOS	10		/* Start of OS-specific */
+#define STB_HIOS	12		/* End of OS-specific */
+#define STB_LOPROC	13		/* Start of processor-specific */
+#define STB_HIPROC	15		/* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_NOTYPE	0		/* Symbol type is unspecified */
+#define STT_OBJECT	1		/* Symbol is a data object */
+#define STT_FUNC	2		/* Symbol is a code object */
+#define STT_SECTION	3		/* Symbol associated with a section */
+#define STT_FILE	4		/* Symbol's name is file name */
+#define STT_COMMON	5		/* Symbol is a common data object */
+#define STT_TLS		6		/* Symbol is thread-local data object*/
+#define	STT_NUM		7		/* Number of defined types.  */
+#define STT_LOOS	10		/* Start of OS-specific */
+#define STT_HIOS	12		/* End of OS-specific */
+#define STT_LOPROC	13		/* Start of processor-specific */
+#define STT_HIPROC	15		/* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+#define STN_UNDEF	0		/* End of a chain.  */
+
+
+/* How to extract and insert information held in the st_other field.  */
+
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
+
+/* For ELF64 the definitions are the same.  */
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field.  */
+#define STV_DEFAULT	0		/* Default symbol visibility rules */
+#define STV_INTERNAL	1		/* Processor specific hidden class */
+#define STV_HIDDEN	2		/* Sym unavailable in other modules */
+#define STV_PROTECTED	3		/* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+} Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+   Elf64_Rela structures, so we'll leave them out until Novell (or
+   whoever) gets their act together.  */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+} Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+  Elf32_Sword	r_addend;		/* Addend */
+} Elf32_Rela;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word	p_type;			/* Segment type */
+  Elf32_Off	p_offset;		/* Segment file offset */
+  Elf32_Addr	p_vaddr;		/* Segment virtual address */
+  Elf32_Addr	p_paddr;		/* Segment physical address */
+  Elf32_Word	p_filesz;		/* Segment size in file */
+  Elf32_Word	p_memsz;		/* Segment size in memory */
+  Elf32_Word	p_flags;		/* Segment flags */
+  Elf32_Word	p_align;		/* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word	p_type;			/* Segment type */
+  Elf64_Word	p_flags;		/* Segment flags */
+  Elf64_Off	p_offset;		/* Segment file offset */
+  Elf64_Addr	p_vaddr;		/* Segment virtual address */
+  Elf64_Addr	p_paddr;		/* Segment physical address */
+  Elf64_Xword	p_filesz;		/* Segment size in file */
+  Elf64_Xword	p_memsz;		/* Segment size in memory */
+  Elf64_Xword	p_align;		/* Segment alignment */
+} Elf64_Phdr;
+
+/* Legal values for p_type (segment type).  */
+
+#define	PT_NULL		0		/* Program header table entry unused */
+#define PT_LOAD		1		/* Loadable program segment */
+#define PT_DYNAMIC	2		/* Dynamic linking information */
+#define PT_INTERP	3		/* Program interpreter */
+#define PT_NOTE		4		/* Auxiliary information */
+#define PT_SHLIB	5		/* Reserved */
+#define PT_PHDR		6		/* Entry for header table itself */
+#define PT_TLS		7		/* Thread-local storage segment */
+#define	PT_NUM		8		/* Number of defined types */
+#define PT_LOOS		0x60000000	/* Start of OS-specific */
+#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK	0x6474e551	/* Indicates stack executability */
+#define PT_GNU_RELRO	0x6474e552	/* Read-only after relocation */
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
+#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff	/* End of OS-specific */
+#define PT_LOPROC	0x70000000	/* Start of processor-specific */
+#define PT_HIPROC	0x7fffffff	/* End of processor-specific */
+
+/* Legal values for p_flags (segment flags).  */
+
+#define PF_X		(1 << 0)	/* Segment is executable */
+#define PF_W		(1 << 1)	/* Segment is writable */
+#define PF_R		(1 << 2)	/* Segment is readable */
+#define PF_MASKOS	0x0ff00000	/* OS-specific */
+#define PF_MASKPROC	0xf0000000	/* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
+#define NT_FPREGSET	2		/* Contains copy of fpregset struct */
+#define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
+#define NT_PRXREG	4		/* Contains copy of prxregset struct */
+#define NT_TASKSTRUCT	4		/* Contains copy of task structure */
+#define NT_PLATFORM	5		/* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV		6		/* Contains copy of auxv array */
+#define NT_GWINDOWS	7		/* Contains copy of gwindows struct */
+#define NT_ASRS		8		/* Contains copy of asrset struct */
+#define NT_PSTATUS	10		/* Contains copy of pstatus struct */
+#define NT_PSINFO	13		/* Contains copy of psinfo struct */
+#define NT_PRCRED	14		/* Contains copy of prcred struct */
+#define NT_UTSNAME	15		/* Contains copy of utsname struct */
+#define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG	20		/* Contains copy of fprxregset struct */
+#define NT_PRXFPREG	0x46e62b7f	/* Contains copy of user_fxsr_struct */
+
+/* Legal values for the note segment descriptor types for object files.  */
+
+#define NT_VERSION	1		/* Contains a version string.  */
+
+
+/* Dynamic section entry.  */
+
+typedef struct
+{
+  Elf32_Sword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf32_Word d_val;			/* Integer value */
+      Elf32_Addr d_ptr;			/* Address value */
+    } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+  Elf64_Sxword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf64_Xword d_val;		/* Integer value */
+      Elf64_Addr d_ptr;			/* Address value */
+    } d_un;
+} Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type).  */
+
+#define DT_NULL		0		/* Marks end of dynamic section */
+#define DT_NEEDED	1		/* Name of needed library */
+#define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
+#define DT_PLTGOT	3		/* Processor defined value */
+#define DT_HASH		4		/* Address of symbol hash table */
+#define DT_STRTAB	5		/* Address of string table */
+#define DT_SYMTAB	6		/* Address of symbol table */
+#define DT_RELA		7		/* Address of Rela relocs */
+#define DT_RELASZ	8		/* Total size of Rela relocs */
+#define DT_RELAENT	9		/* Size of one Rela reloc */
+#define DT_STRSZ	10		/* Size of string table */
+#define DT_SYMENT	11		/* Size of one symbol table entry */
+#define DT_INIT		12		/* Address of init function */
+#define DT_FINI		13		/* Address of termination function */
+#define DT_SONAME	14		/* Name of shared object */
+#define DT_RPATH	15		/* Library search path (deprecated) */
+#define DT_SYMBOLIC	16		/* Start symbol search here */
+#define DT_REL		17		/* Address of Rel relocs */
+#define DT_RELSZ	18		/* Total size of Rel relocs */
+#define DT_RELENT	19		/* Size of one Rel reloc */
+#define DT_PLTREL	20		/* Type of reloc in PLT */
+#define DT_DEBUG	21		/* For debugging; unspecified */
+#define DT_TEXTREL	22		/* Reloc might modify .text */
+#define DT_JMPREL	23		/* Address of PLT relocs */
+#define	DT_BIND_NOW	24		/* Process relocations of object */
+#define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
+#define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
+#define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
+#define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH	29		/* Library search path */
+#define DT_FLAGS	30		/* Flags for the object being loaded */
+#define DT_ENCODING	32		/* Start of encoded range */
+#define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
+#define	DT_NUM		34		/* Number used */
+#define DT_LOOS		0x6000000d	/* Start of OS-specific */
+#define DT_HIOS		0x6ffff000	/* End of OS-specific */
+#define DT_LOPROC	0x70000000	/* Start of processor-specific */
+#define DT_HIPROC	0x7fffffff	/* End of processor-specific */
+#define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
+   approach.  */
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5	/* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6	/* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7	/* Size of library list */
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc	/* Feature selection (DTF_*).  */
+#define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
+					   the following DT_* entry.  */
+#define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
+#define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))	/* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+   If any adjustment is made to the ELF object after it has been
+   built these entries will need to be adjusted.  */
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_HASH	0x6ffffef5	/* GNU-style hash table.  */
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#define DT_GNU_CONFLICT	0x6ffffef8	/* Start of conflict section */
+#define DT_GNU_LIBLIST	0x6ffffef9	/* Library list */
+#define DT_CONFIG	0x6ffffefa	/* Configuration information.  */
+#define DT_DEPAUDIT	0x6ffffefb	/* Dependency auditing.  */
+#define DT_AUDIT	0x6ffffefc	/* Object auditing.  */
+#define	DT_PLTPAD	0x6ffffefd	/* PLT padding.  */
+#define	DT_MOVETAB	0x6ffffefe	/* Move table.  */
+#define DT_SYMINFO	0x6ffffeff	/* Syminfo table.  */
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
+#define DT_ADDRNUM 11
+
+/* The versioning entry types.  The next are defined as part of the
+   GNU extension.  */
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+/* These were chosen by Sun.  */
+#define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
+#define	DT_VERDEF	0x6ffffffc	/* Address of version definition
+					   table */
+#define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
+#define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
+					   versions */
+#define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
+#define DF_ORIGIN	0x00000001	/* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC	0x00000002	/* Symbol resolutions starts here */
+#define DF_TEXTREL	0x00000004	/* Object contains text relocations */
+#define DF_BIND_NOW	0x00000008	/* No lazy binding for this object */
+#define DF_STATIC_TLS	0x00000010	/* Module uses the static TLS model */
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+   entry in the dynamic section.  */
+#define DF_1_NOW	0x00000001	/* Set RTLD_NOW for this object.  */
+#define DF_1_GLOBAL	0x00000002	/* Set RTLD_GLOBAL for this object.  */
+#define DF_1_GROUP	0x00000004	/* Set RTLD_GROUP for this object.  */
+#define DF_1_NODELETE	0x00000008	/* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR	0x00000010	/* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST	0x00000020	/* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN	0x00000040	/* Set RTLD_NOOPEN for this object.  */
+#define DF_1_ORIGIN	0x00000080	/* $ORIGIN must be handled.  */
+#define DF_1_DIRECT	0x00000100	/* Direct binding enabled.  */
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400	/* Object is used to interpose.  */
+#define DF_1_NODEFLIB	0x00000800	/* Ignore default lib search path.  */
+#define DF_1_NODUMP	0x00001000	/* Object can't be dldump'ed.  */
+#define DF_1_CONFALT	0x00002000	/* Configuration alternative created.*/
+#define DF_1_ENDFILTEE	0x00004000	/* Filtee terminates filters search. */
+#define	DF_1_DISPRELDNE	0x00008000	/* Disp reloc applied at build time. */
+#define	DF_1_DISPRELPND	0x00010000	/* Disp reloc applied at run-time.  */
+
+/* Flags for the feature selection in DT_FEATURE_1.  */
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
+#define DF_P1_LAZYLOAD	0x00000001	/* Lazyload following object.  */
+#define DF_P1_GROUPPERM	0x00000002	/* Symbols from next object are not
+					   generally available.  */
+
+/* Version definition sections.  */
+
+typedef struct
+{
+  Elf32_Half	vd_version;		/* Version revision */
+  Elf32_Half	vd_flags;		/* Version information */
+  Elf32_Half	vd_ndx;			/* Version Index */
+  Elf32_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vd_hash;		/* Version name hash value */
+  Elf32_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf32_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} Elf32_Verdef;
+
+typedef struct
+{
+  Elf64_Half	vd_version;		/* Version revision */
+  Elf64_Half	vd_flags;		/* Version information */
+  Elf64_Half	vd_ndx;			/* Version Index */
+  Elf64_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vd_hash;		/* Version name hash value */
+  Elf64_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf64_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision).  */
+#define VER_DEF_NONE	0		/* No version */
+#define VER_DEF_CURRENT	1		/* Current version */
+#define VER_DEF_NUM	2		/* Given version number */
+
+/* Legal values for vd_flags (version information flags).  */
+#define VER_FLG_BASE	0x1		/* Version definition of file itself */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+/* Versym symbol index values.  */
+#define	VER_NDX_LOCAL		0	/* Symbol is local.  */
+#define	VER_NDX_GLOBAL		1	/* Symbol is global.  */
+#define	VER_NDX_LORESERVE	0xff00	/* Beginning of reserved entries.  */
+#define	VER_NDX_ELIMINATE	0xff01	/* Symbol is to be eliminated.  */
+
+/* Auxialiary version information.  */
+
+typedef struct
+{
+  Elf32_Word	vda_name;		/* Version or dependency names */
+  Elf32_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} Elf32_Verdaux;
+
+typedef struct
+{
+  Elf64_Word	vda_name;		/* Version or dependency names */
+  Elf64_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} Elf64_Verdaux;
+
+
+/* Version dependency section.  */
+
+typedef struct
+{
+  Elf32_Half	vn_version;		/* Version of structure */
+  Elf32_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf32_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf32_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} Elf32_Verneed;
+
+typedef struct
+{
+  Elf64_Half	vn_version;		/* Version of structure */
+  Elf64_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf64_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf64_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision).  */
+#define VER_NEED_NONE	 0		/* No version */
+#define VER_NEED_CURRENT 1		/* Current version */
+#define VER_NEED_NUM	 2		/* Given version number */
+
+/* Auxiliary needed version information.  */
+
+typedef struct
+{
+  Elf32_Word	vna_hash;		/* Hash value of dependency name */
+  Elf32_Half	vna_flags;		/* Dependency specific information */
+  Elf32_Half	vna_other;		/* Unused */
+  Elf32_Word	vna_name;		/* Dependency name string offset */
+  Elf32_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} Elf32_Vernaux;
+
+typedef struct
+{
+  Elf64_Word	vna_hash;		/* Hash value of dependency name */
+  Elf64_Half	vna_flags;		/* Dependency specific information */
+  Elf64_Half	vna_other;		/* Unused */
+  Elf64_Word	vna_name;		/* Dependency name string offset */
+  Elf64_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} Elf64_Vernaux;
+
+
+/* Legal values for vna_flags.  */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+
+/* Auxiliary vector.  */
+
+/* This vector is normally only used by the program interpreter.  The
+   usual definition in an ABI supplement uses the name auxv_t.  The
+   vector is not usually defined in a standard <elf.h> file, but it
+   can't hurt.  We rename it to avoid conflicts.  The sizes of these
+   types are an arrangement between the exec server and the program
+   interpreter, so we don't fully specify them here.  */
+
+typedef struct
+{
+  unsigned int a_type;		/* Entry type */
+  union
+    {
+      unsigned int a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
+    } a_un;
+} Elf32_auxv_t;
+
+typedef struct
+{
+  unsigned long a_type;		/* Entry type */
+  union
+    {
+      unsigned long a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
+    } a_un;
+} Elf64_auxv_t;
+
+/* Legal values for a_type (entry type).  */
+
+#define AT_NULL		0		/* End of vector */
+#define AT_IGNORE	1		/* Entry should be ignored */
+#define AT_EXECFD	2		/* File descriptor of program */
+#define AT_PHDR		3		/* Program headers for program */
+#define AT_PHENT	4		/* Size of program header entry */
+#define AT_PHNUM	5		/* Number of program headers */
+#define AT_PAGESZ	6		/* System page size */
+#define AT_BASE		7		/* Base address of interpreter */
+#define AT_FLAGS	8		/* Flags */
+#define AT_ENTRY	9		/* Entry point of program */
+#define AT_NOTELF	10		/* Program is not ELF */
+#define AT_UID		11		/* Real uid */
+#define AT_EUID		12		/* Effective uid */
+#define AT_GID		13		/* Real gid */
+#define AT_EGID		14		/* Effective gid */
+#define AT_CLKTCK	17		/* Frequency of times() */
+
+/* Some more special a_type values describing the hardware.  */
+#define AT_PLATFORM	15		/* String identifying platform.  */
+#define AT_HWCAP	16		/* Machine dependent hints about
+					   processor capabilities.  */
+
+/* This entry gives some information about the FPU initialization
+   performed by the kernel.  */
+#define AT_FPUCW	18		/* Used FPU control word.  */
+
+/* Cache block sizes.  */
+#define AT_DCACHEBSIZE	19		/* Data cache block size.  */
+#define AT_ICACHEBSIZE	20		/* Instruction cache block size.  */
+#define AT_UCACHEBSIZE	21		/* Unified cache block size.  */
+
+/* A special ignored value for PPC, used by the kernel to control the
+   interpretation of the AUXV. Must be > 16.  */
+#define AT_IGNOREPPC	22		/* Entry should be ignored.  */
+
+#define	AT_SECURE	23		/* Boolean, was exec setuid-like?  */
+
+/* Pointer to the global system page used for system calls and other
+   nice things.  */
+#define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
+
+/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
+   log2 of line size; mask those to get cache size.  */
+#define AT_L1I_CACHESHAPE	34
+#define AT_L1D_CACHESHAPE	35
+#define AT_L2_CACHESHAPE	36
+#define AT_L3_CACHESHAPE	37
+
+/* Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+typedef struct
+{
+  Elf32_Word n_namesz;			/* Length of the note's name.  */
+  Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf32_Word n_type;			/* Type of the note.  */
+} Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;			/* Length of the note's name.  */
+  Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf64_Word n_type;			/* Type of the note.  */
+} Elf64_Nhdr;
+
+/* Known names of notes.  */
+
+/* Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+/* Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU		"GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/* Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+/* Defined note types for GNU systems.  */
+
+/* ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define NT_GNU_ABI_TAG	1
+#define ELF_NOTE_ABI	NT_GNU_ABI_TAG /* Old name.  */
+
+/* Known OSes.  These values can appear in word 0 of an
+   NT_GNU_ABI_TAG note section entry.  */
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+#define ELF_NOTE_OS_FREEBSD	3
+
+/* Synthetic hwcap information.  The descriptor begins with two words:
+   word 0: number of entries
+   word 1: bitmask of enabled entries
+   Then follow variable-length entries, one byte followed by a
+   '\0'-terminated hwcap name string.  The byte gives the bit
+   number to test if enabled, (1U << bit) & bitmask.  */
+#define NT_GNU_HWCAP	2
+
+/* Build ID bits as generated by ld --build-id.
+   The descriptor consists of any nonzero number of bytes.  */
+#define NT_GNU_BUILD_ID	3
+
+
+/* Move records.  */
+typedef struct
+{
+  Elf32_Xword m_value;		/* Symbol value.  */
+  Elf32_Word m_info;		/* Size and index.  */
+  Elf32_Word m_poffset;		/* Symbol offset.  */
+  Elf32_Half m_repeat;		/* Repeat count.  */
+  Elf32_Half m_stride;		/* Stride info.  */
+} Elf32_Move;
+
+typedef struct
+{
+  Elf64_Xword m_value;		/* Symbol value.  */
+  Elf64_Xword m_info;		/* Size and index.  */
+  Elf64_Xword m_poffset;	/* Symbol offset.  */
+  Elf64_Half m_repeat;		/* Repeat count.  */
+  Elf64_Half m_stride;		/* Stride info.  */
+} Elf64_Move;
+
+/* Macro to construct move records.  */
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
+
+
+/* Motorola 68k specific definitions.  */
+
+/* Values for Elf32_Ehdr.e_flags.  */
+#define EF_CPU32	0x00810000
+
+/* m68k relocs.  */
+
+#define R_68K_NONE	0		/* No reloc */
+#define R_68K_32	1		/* Direct 32 bit  */
+#define R_68K_16	2		/* Direct 16 bit  */
+#define R_68K_8		3		/* Direct 8 bit  */
+#define R_68K_PC32	4		/* PC relative 32 bit */
+#define R_68K_PC16	5		/* PC relative 16 bit */
+#define R_68K_PC8	6		/* PC relative 8 bit */
+#define R_68K_GOT32	7		/* 32 bit PC relative GOT entry */
+#define R_68K_GOT16	8		/* 16 bit PC relative GOT entry */
+#define R_68K_GOT8	9		/* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O	10		/* 32 bit GOT offset */
+#define R_68K_GOT16O	11		/* 16 bit GOT offset */
+#define R_68K_GOT8O	12		/* 8 bit GOT offset */
+#define R_68K_PLT32	13		/* 32 bit PC relative PLT address */
+#define R_68K_PLT16	14		/* 16 bit PC relative PLT address */
+#define R_68K_PLT8	15		/* 8 bit PC relative PLT address */
+#define R_68K_PLT32O	16		/* 32 bit PLT offset */
+#define R_68K_PLT16O	17		/* 16 bit PLT offset */
+#define R_68K_PLT8O	18		/* 8 bit PLT offset */
+#define R_68K_COPY	19		/* Copy symbol at runtime */
+#define R_68K_GLOB_DAT	20		/* Create GOT entry */
+#define R_68K_JMP_SLOT	21		/* Create PLT entry */
+#define R_68K_RELATIVE	22		/* Adjust by program base */
+/* Keep this the last entry.  */
+#define R_68K_NUM	23
+
+/* Intel 80386 specific definitions.  */
+
+/* i386 relocs.  */
+
+#define R_386_NONE	   0		/* No reloc */
+#define R_386_32	   1		/* Direct 32 bit  */
+#define R_386_PC32	   2		/* PC relative 32 bit */
+#define R_386_GOT32	   3		/* 32 bit GOT entry */
+#define R_386_PLT32	   4		/* 32 bit PLT address */
+#define R_386_COPY	   5		/* Copy symbol at runtime */
+#define R_386_GLOB_DAT	   6		/* Create GOT entry */
+#define R_386_JMP_SLOT	   7		/* Create PLT entry */
+#define R_386_RELATIVE	   8		/* Adjust by program base */
+#define R_386_GOTOFF	   9		/* 32 bit offset to GOT */
+#define R_386_GOTPC	   10		/* 32 bit PC relative offset to GOT */
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14		/* Offset in static TLS block */
+#define R_386_TLS_IE	   15		/* Address of GOT entry for static TLS
+					   block offset */
+#define R_386_TLS_GOTIE	   16		/* GOT entry for static TLS block
+					   offset */
+#define R_386_TLS_LE	   17		/* Offset relative to static TLS
+					   block */
+#define R_386_TLS_GD	   18		/* Direct 32 bit for GNU version of
+					   general dynamic thread local data */
+#define R_386_TLS_LDM	   19		/* Direct 32 bit for GNU version of
+					   local dynamic thread local data
+					   in LE code */
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24		/* Direct 32 bit for general dynamic
+					   thread local data */
+#define R_386_TLS_GD_PUSH  25		/* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL  26		/* Relocation for call to
+					   __tls_get_addr() */
+#define R_386_TLS_GD_POP   27		/* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32   28		/* Direct 32 bit for local dynamic
+					   thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29		/* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30		/* Relocation for call to
+					   __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP  31		/* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32   32		/* Offset relative to TLS block */
+#define R_386_TLS_IE_32	   33		/* GOT entry for negated static TLS
+					   block offset */
+#define R_386_TLS_LE_32	   34		/* Negated offset relative to static
+					   TLS block */
+#define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
+#define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
+/* Keep this the last entry.  */
+#define R_386_NUM	   38
+
+/* SUN SPARC specific definitions.  */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_SPARC_REGISTER	13	/* Global register reserved to app. */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1	0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1		0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3	0x000800 /* Sun UltraSPARCIII extensions */
+
+/* SPARC relocs.  */
+
+#define R_SPARC_NONE		0	/* No reloc */
+#define R_SPARC_8		1	/* Direct 8 bit */
+#define R_SPARC_16		2	/* Direct 16 bit */
+#define R_SPARC_32		3	/* Direct 32 bit */
+#define R_SPARC_DISP8		4	/* PC relative 8 bit */
+#define R_SPARC_DISP16		5	/* PC relative 16 bit */
+#define R_SPARC_DISP32		6	/* PC relative 32 bit */
+#define R_SPARC_WDISP30		7	/* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22		8	/* PC relative 22 bit shifted */
+#define R_SPARC_HI22		9	/* High 22 bit */
+#define R_SPARC_22		10	/* Direct 22 bit */
+#define R_SPARC_13		11	/* Direct 13 bit */
+#define R_SPARC_LO10		12	/* Truncated 10 bit */
+#define R_SPARC_GOT10		13	/* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13		14	/* 13 bit GOT entry */
+#define R_SPARC_GOT22		15	/* 22 bit GOT entry shifted */
+#define R_SPARC_PC10		16	/* PC relative 10 bit truncated */
+#define R_SPARC_PC22		17	/* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30		18	/* 30 bit PC relative PLT address */
+#define R_SPARC_COPY		19	/* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT	20	/* Create GOT entry */
+#define R_SPARC_JMP_SLOT	21	/* Create PLT entry */
+#define R_SPARC_RELATIVE	22	/* Adjust by program base */
+#define R_SPARC_UA32		23	/* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs.  */
+
+#define R_SPARC_PLT32		24	/* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22		25	/* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10		26	/* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32		27	/* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22		28	/* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10		29	/* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10		30	/* Direct 10 bit */
+#define R_SPARC_11		31	/* Direct 11 bit */
+#define R_SPARC_64		32	/* Direct 64 bit */
+#define R_SPARC_OLO10		33	/* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22		34	/* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10		35	/* High middle 10 bits of ... */
+#define R_SPARC_LM22		36	/* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22		37	/* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10		38	/* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22		39	/* Low miggle 22 bits of ... */
+#define R_SPARC_WDISP16		40	/* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19		41	/* PC relative 19 bit shifted */
+#define R_SPARC_7		43	/* Direct 7 bit */
+#define R_SPARC_5		44	/* Direct 5 bit */
+#define R_SPARC_6		45	/* Direct 6 bit */
+#define R_SPARC_DISP64		46	/* PC relative 64 bit */
+#define R_SPARC_PLT64		47	/* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22		48	/* High 22 bit complemented */
+#define R_SPARC_LOX10		49	/* Truncated 11 bit complemented */
+#define R_SPARC_H44		50	/* Direct high 12 of 44 bit */
+#define R_SPARC_M44		51	/* Direct mid 22 of 44 bit */
+#define R_SPARC_L44		52	/* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER	53	/* Global register usage */
+#define R_SPARC_UA64		54	/* Direct 64 bit unaligned */
+#define R_SPARC_UA16		55	/* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+/* Keep this the last entry.  */
+#define R_SPARC_NUM		80
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM	2
+
+/* Bits present in AT_HWCAP on SPARC.  */
+
+#define HWCAP_SPARC_FLUSH	1	/* The CPU supports flush insn.  */
+#define HWCAP_SPARC_STBAR	2
+#define HWCAP_SPARC_SWAP	4
+#define HWCAP_SPARC_MULDIV	8
+#define HWCAP_SPARC_V9		16	/* The CPU is v9, so v8plus is ok.  */
+#define HWCAP_SPARC_ULTRA3	32
+#define HWCAP_SPARC_BLKINIT	64	/* Sun4v with block-init/load-twin.  */
+#define HWCAP_SPARC_N2		128
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
+#define EF_MIPS_PIC	    2		/* Contains PIC code */
+#define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
+#define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
+#define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
+#define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
+#define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
+#define EF_MIPS_ARCH_32	    0x60000000	/* MIPS32 code.  */
+#define EF_MIPS_ARCH_64	    0x70000000	/* MIPS64 code.  */
+
+/* The following are non-official names and should not be used.  */
+
+#define E_MIPS_ARCH_1	  0x00000000	/* -mips1 code.  */
+#define E_MIPS_ARCH_2	  0x10000000	/* -mips2 code.  */
+#define E_MIPS_ARCH_3	  0x20000000	/* -mips3 code.  */
+#define E_MIPS_ARCH_4	  0x30000000	/* -mips4 code.  */
+#define E_MIPS_ARCH_5	  0x40000000	/* -mips5 code.  */
+#define E_MIPS_ARCH_32	  0x60000000	/* MIPS32 code.  */
+#define E_MIPS_ARCH_64	  0x70000000	/* MIPS64 code.  */
+
+/* Special section indices.  */
+
+#define SHN_MIPS_ACOMMON    0xff00	/* Allocated common symbols */
+#define SHN_MIPS_TEXT	    0xff01	/* Allocated test symbols.  */
+#define SHN_MIPS_DATA	    0xff02	/* Allocated data symbols.  */
+#define SHN_MIPS_SCOMMON    0xff03	/* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04	/* Small undefined symbols */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
+#define SHT_MIPS_MSYM	       0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
+#define SHT_MIPS_GPTAB	       0x70000003 /* Global data area sizes */
+#define SHT_MIPS_UCODE	       0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG	       0x70000005 /* MIPS ECOFF debugging information*/
+#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD	       0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
+#define SHT_MIPS_SHDR	       0x70000010
+#define SHT_MIPS_FDESC	       0x70000011
+#define SHT_MIPS_EXTSYM	       0x70000012
+#define SHT_MIPS_DENSE	       0x70000013
+#define SHT_MIPS_PDESC	       0x70000014
+#define SHT_MIPS_LOCSYM	       0x70000015
+#define SHT_MIPS_AUXSYM	       0x70000016
+#define SHT_MIPS_OPTSYM	       0x70000017
+#define SHT_MIPS_LOCSTR	       0x70000018
+#define SHT_MIPS_LINE	       0x70000019
+#define SHT_MIPS_RFDESC	       0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS	       0x70000021 /* Event section.  */
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE	       0x70000023
+#define SHT_MIPS_XLATE	       0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL	       0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_MIPS_GPREL	 0x10000000	/* Must be part of global data area */
+#define SHF_MIPS_MERGE	 0x20000000
+#define SHF_MIPS_ADDR	 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL	 0x04000000
+#define SHF_MIPS_NAMES	 0x02000000
+#define SHF_MIPS_NODUPE	 0x01000000
+
+
+/* Symbol tables.  */
+
+/* MIPS specific values for `st_other'.  */
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+/* MIPS specific values for `st_info'.  */
+#define STB_MIPS_SPLIT_COMMON		13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB.  */
+
+typedef union
+{
+  struct
+    {
+      Elf32_Word gt_current_g_value;	/* -G value used for compilation */
+      Elf32_Word gt_unused;		/* Not used */
+    } gt_header;			/* First entry in section */
+  struct
+    {
+      Elf32_Word gt_g_value;		/* If this value were used for -G */
+      Elf32_Word gt_bytes;		/* This many bytes would be used */
+    } gt_entry;				/* Subsequent entries in section */
+} Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO.  */
+
+typedef struct
+{
+  Elf32_Word	ri_gprmask;		/* General registers used */
+  Elf32_Word	ri_cprmask[4];		/* Coprocessor registers used */
+  Elf32_Sword	ri_gp_value;		/* $gp register value */
+} Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
+
+typedef struct
+{
+  unsigned char kind;		/* Determines interpretation of the
+				   variable part of descriptor.  */
+  unsigned char size;		/* Size of descriptor, including header.  */
+  Elf32_Section section;	/* Section header index of section affected,
+				   0 for global options.  */
+  Elf32_Word info;		/* Kind-specific information.  */
+} Elf_Options;
+
+/* Values for `kind' field in Elf_Options.  */
+
+#define ODK_NULL	0	/* Undefined.  */
+#define ODK_REGINFO	1	/* Register usage information.  */
+#define ODK_EXCEPTIONS	2	/* Exception processing options.  */
+#define ODK_PAD		3	/* Section padding options.  */
+#define ODK_HWPATCH	4	/* Hardware workarounds performed */
+#define ODK_FILL	5	/* record the fill value used by the linker. */
+#define ODK_TAGS	6	/* reserve space for desktop tools to write. */
+#define ODK_HWAND	7	/* HW workarounds.  'AND' bits when merging. */
+#define ODK_HWOR	8	/* HW workarounds.  'OR' bits when merging.  */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
+
+#define OEX_FPU_MIN	0x1f	/* FPE's which MUST be enabled.  */
+#define OEX_FPU_MAX	0x1f00	/* FPE's which MAY be enabled.  */
+#define OEX_PAGE0	0x10000	/* page zero must be mapped.  */
+#define OEX_SMM		0x20000	/* Force sequential memory mode?  */
+#define OEX_FPDBUG	0x40000	/* Force floating point debug mode?  */
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000	/* Dismiss invalid address faults?  */
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
+
+#define OHW_R4KEOP	0x1	/* R4000 end-of-page patch.  */
+#define OHW_R8KPFETCH	0x2	/* may need R8000 prefetch patch.  */
+#define OHW_R5KEOP	0x4	/* R5000 end-of-page patch.  */
+#define OHW_R5KCVTL	0x8	/* R5000 cvt.[ds].l bug.  clean=1.  */
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+/* Entry found in `.options' section.  */
+
+typedef struct
+{
+  Elf32_Word hwp_flags1;	/* Extra flags.  */
+  Elf32_Word hwp_flags2;	/* Extra flags.  */
+} Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+/* MIPS relocs.  */
+
+#define R_MIPS_NONE		0	/* No reloc */
+#define R_MIPS_16		1	/* Direct 16 bit */
+#define R_MIPS_32		2	/* Direct 32 bit */
+#define R_MIPS_REL32		3	/* PC relative 32 bit */
+#define R_MIPS_26		4	/* Direct 26 bit shifted */
+#define R_MIPS_HI16		5	/* High 16 bit */
+#define R_MIPS_LO16		6	/* Low 16 bit */
+#define R_MIPS_GPREL16		7	/* GP relative 16 bit */
+#define R_MIPS_LITERAL		8	/* 16 bit literal entry */
+#define R_MIPS_GOT16		9	/* 16 bit GOT entry */
+#define R_MIPS_PC16		10	/* PC relative 16 bit */
+#define R_MIPS_CALL16		11	/* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32		12	/* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+#define R_MIPS_TLS_DTPMOD32	38	/* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32	39	/* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64	40	/* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64	41	/* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD		42	/* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM		43	/* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16	44	/* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16	45	/* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL	46	/* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32	47	/* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
+#define R_MIPS_GLOB_DAT		51
+/* Keep this the last entry.  */
+#define R_MIPS_NUM		52
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
+#define PT_MIPS_RTPROC  0x70000001	/* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL	0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn.  */
+
+#define DT_MIPS_RLD_VERSION  0x70000001	/* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP   0x70000002	/* Timestamp */
+#define DT_MIPS_ICHECKSUM    0x70000003	/* Checksum */
+#define DT_MIPS_IVERSION     0x70000004	/* Version string (string tbl index) */
+#define DT_MIPS_FLAGS	     0x70000005	/* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006	/* Base address */
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008	/* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST	     0x70000009	/* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a	/* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO   0x7000000b	/* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO    0x70000010	/* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO     0x70000011	/* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO   0x70000012	/* First external DYNSYM */
+#define DT_MIPS_GOTSYM	     0x70000013	/* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO     0x70000014	/* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP	     0x70000016	/* Address of run time loader map.  */
+#define DT_MIPS_DELTA_CLASS  0x70000017	/* Delta C++ class definition.  */
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
+						DT_MIPS_DELTA_CLASS.  */
+#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+						DT_MIPS_DELTA_INSTANCE.  */
+#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+					     DT_MIPS_DELTA_RELOC.  */
+#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
+					   relocations refer to.  */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+					   DT_MIPS_DELTA_SYM.  */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+					     class declaration.  */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+						DT_MIPS_DELTA_CLASSSYM.  */
+#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029 /* Address of .options.  */
+#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+						    function stored in GOT.  */
+#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
+					   by rld on dlopen() calls.  */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
+#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
+#define DT_MIPS_NUM	     0x32
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
+
+#define RHF_NONE		   0		/* No flags */
+#define RHF_QUICKSTART		   (1 << 0)	/* Use quickstart */
+#define RHF_NOTPOT		   (1 << 1)	/* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)	/* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
+
+typedef struct
+{
+  Elf32_Word l_name;		/* Name (string table index) */
+  Elf32_Word l_time_stamp;	/* Timestamp */
+  Elf32_Word l_checksum;	/* Checksum */
+  Elf32_Word l_version;		/* Interface version */
+  Elf32_Word l_flags;		/* Flags */
+} Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;		/* Name (string table index) */
+  Elf64_Word l_time_stamp;	/* Timestamp */
+  Elf64_Word l_checksum;	/* Checksum */
+  Elf64_Word l_version;		/* Interface version */
+  Elf64_Word l_flags;		/* Flags */
+} Elf64_Lib;
+
+
+/* Legal values for l_flags.  */
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)	/* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1)	/* Ignore interface version */
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNIL	0x00010000 /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT		0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB		0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE		0x00080000 /* Program expects wide mode.  */
+#define EF_PARISC_NO_KABP	0x00100000 /* No kernel assisted branch
+					      prediction.  */
+#define EF_PARISC_LAZYSWAP	0x00400000 /* Allow lazy swapping.  */
+#define EF_PARISC_ARCH		0x0000ffff /* Architecture version.  */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
+
+#define EFA_PARISC_1_0		    0x020b /* PA-RISC 1.0 big-endian.  */
+#define EFA_PARISC_1_1		    0x0210 /* PA-RISC 1.1 big-endian.  */
+#define EFA_PARISC_2_0		    0x0214 /* PA-RISC 2.0 big-endian.  */
+
+/* Additional section indeces.  */
+
+#define SHN_PARISC_ANSI_COMMON	0xff00	   /* Section for tenatively declared
+					      symbols in ANSI C.  */
+#define SHN_PARISC_HUGE_COMMON	0xff01	   /* Common blocks in huge model.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_EXT		0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND	0x70000001 /* Unwind information.  */
+#define SHT_PARISC_DOC		0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE		0x40000000 /* Section far from gp.  */
+#define SHF_PARISC_SBP		0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE		0	/* No reloc.  */
+#define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR17F		4	/* 17 bits of eff. address.  */
+#define R_PARISC_DIR14R		6	/* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL32	9	/* 32-bit rel. address.  */
+#define R_PARISC_PCREL21L	10	/* Left 21 bits of rel. address.  */
+#define R_PARISC_PCREL17R	11	/* Right 17 bits of rel. address.  */
+#define R_PARISC_PCREL17F	12	/* 17 bits of rel. address.  */
+#define R_PARISC_PCREL14R	14	/* Right 14 bits of rel. address.  */
+#define R_PARISC_DPREL21L	18	/* Left 21 bits of rel. address.  */
+#define R_PARISC_DPREL14R	22	/* Right 14 bits of rel. address.  */
+#define R_PARISC_GPREL21L	26	/* GP-relative, left 21 bits.  */
+#define R_PARISC_GPREL14R	30	/* GP-relative, right 14 bits.  */
+#define R_PARISC_LTOFF21L	34	/* LT-relative, left 21 bits.  */
+#define R_PARISC_LTOFF14R	38	/* LT-relative, right 14 bits.  */
+#define R_PARISC_SECREL32	41	/* 32 bits section rel. address.  */
+#define R_PARISC_SEGBASE	48	/* No relocation, set segment base.  */
+#define R_PARISC_SEGREL32	49	/* 32 bits segment rel. address.  */
+#define R_PARISC_PLTOFF21L	50	/* PLT rel. address, left 21 bits.  */
+#define R_PARISC_PLTOFF14R	54	/* PLT rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_FPTR32	57	/* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L	58	/* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R	62	/* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64		64	/* 64 bits function address.  */
+#define R_PARISC_PLABEL32	65	/* 32 bits function address.  */
+#define R_PARISC_PLABEL21L	66	/* Left 21 bits of fdesc address.  */
+#define R_PARISC_PLABEL14R	70	/* Right 14 bits of fdesc address.  */
+#define R_PARISC_PCREL64	72	/* 64 bits PC-rel. address.  */
+#define R_PARISC_PCREL22F	74	/* 22 bits PC-rel. address.  */
+#define R_PARISC_PCREL14WR	75	/* PC-rel. address, right 14 bits.  */
+#define R_PARISC_PCREL14DR	76	/* PC rel. address, right 14 bits.  */
+#define R_PARISC_PCREL16F	77	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16WF	78	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16DF	79	/* 16 bits PC-rel. address.  */
+#define R_PARISC_DIR64		80	/* 64 bits of eff. address.  */
+#define R_PARISC_DIR14WR	83	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR14DR	84	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR16F		85	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16WF	86	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16DF	87	/* 16 bits of eff. address.  */
+#define R_PARISC_GPREL64	88	/* 64 bits of GP-rel. address.  */
+#define R_PARISC_GPREL14WR	91	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL14DR	92	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL16F	93	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16WF	94	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16DF	95	/* 16 bits GP-rel. address.  */
+#define R_PARISC_LTOFF64	96	/* 64 bits LT-rel. address.  */
+#define R_PARISC_LTOFF14WR	99	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF14DR	100	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF16F	101	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16WF	102	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16DF	103	/* 16 bits LT-rel. address.  */
+#define R_PARISC_SECREL64	104	/* 64 bits section rel. address.  */
+#define R_PARISC_SEGREL64	112	/* 64 bits segment rel. address.  */
+#define R_PARISC_PLTOFF14WR	115	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF14DR	116	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF16F	117	/* 16 bits LT-rel. address.  */
+#define R_PARISC_PLTOFF16WF	118	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_PLTOFF16DF	119	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_LTOFF_FPTR64	120	/* 64 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR14WR	123	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR	124	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F	125	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16WF	126	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16DF	127	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128	/* Copy relocation.  */
+#define R_PARISC_IPLT		129	/* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT		130	/* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32	153	/* 32 bits TP-rel. address.  */
+#define R_PARISC_TPREL21L	154	/* TP-rel. address, left 21 bits.  */
+#define R_PARISC_TPREL14R	158	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_TP21L	162	/* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R	166	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F	167	/* 14 bits LT-TP-rel. address.  */
+#define R_PARISC_TPREL64	216	/* 64 bits TP-rel. address.  */
+#define R_PARISC_TPREL14WR	219	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL14DR	220	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL16F	221	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16WF	222	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16DF	223	/* 16 bits TP-rel. address.  */
+#define R_PARISC_LTOFF_TP64	224	/* 64 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP14WR	227	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR	228	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F	229	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16WF	230	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_GNU_VTENTRY	232
+#define R_PARISC_GNU_VTINHERIT	233
+#define R_PARISC_TLS_GD21L	234	/* GD 21-bit left.  */
+#define R_PARISC_TLS_GD14R	235	/* GD 14-bit right.  */
+#define R_PARISC_TLS_GDCALL	236	/* GD call to __t_g_a.  */
+#define R_PARISC_TLS_LDM21L	237	/* LD module 21-bit left.  */
+#define R_PARISC_TLS_LDM14R	238	/* LD module 14-bit right.  */
+#define R_PARISC_TLS_LDMCALL	239	/* LD module call to __t_g_a.  */
+#define R_PARISC_TLS_LDO21L	240	/* LD offset 21-bit left.  */
+#define R_PARISC_TLS_LDO14R	241	/* LD offset 14-bit right.  */
+#define R_PARISC_TLS_DTPMOD32	242	/* DTP module 32-bit.  */
+#define R_PARISC_TLS_DTPMOD64	243	/* DTP module 64-bit.  */
+#define R_PARISC_TLS_DTPOFF32	244	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_DTPOFF64	245	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE	255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
+
+/* Legal values for sh_type field of Elf64_Shdr.  */
+
+/* These two are primerily concerned with ECOFF debugging info.  */
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr.  */
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+/* Legal values for st_other field of Elf64_Sym.  */
+#define STO_ALPHA_NOPV		0x80	/* No PV required.  */
+#define STO_ALPHA_STD_GPLOAD	0x88	/* PV only used for initial ldgp.  */
+
+/* Alpha relocs.  */
+
+#define R_ALPHA_NONE		0	/* No reloc */
+#define R_ALPHA_REFLONG		1	/* Direct 32 bit */
+#define R_ALPHA_REFQUAD		2	/* Direct 64 bit */
+#define R_ALPHA_GPREL32		3	/* GP relative 32 bit */
+#define R_ALPHA_LITERAL		4	/* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE		5	/* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP		6	/* Add displacement to GP */
+#define R_ALPHA_BRADDR		7	/* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT		8	/* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16		9	/* PC relative 16 bit */
+#define R_ALPHA_SREL32		10	/* PC relative 32 bit */
+#define R_ALPHA_SREL64		11	/* PC relative 64 bit */
+#define R_ALPHA_GPRELHIGH	17	/* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW	18	/* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16		19	/* GP relative 16 bit */
+#define R_ALPHA_COPY		24	/* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT	25	/* Create GOT entry */
+#define R_ALPHA_JMP_SLOT	26	/* Create PLT entry */
+#define R_ALPHA_RELATIVE	27	/* Adjust by program base */
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+/* Keep this the last entry.  */
+#define R_ALPHA_NUM		46
+
+/* Magic values of the LITUSE relocation addend.  */
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+/* Legal values for d_tag of Elf64_Dyn.  */
+#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
+#define DT_ALPHA_NUM		1
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags.  */
+#define EF_PPC_EMB		0x80000000	/* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB	0x00008000	/* PowerPC -mrelocatable-lib
+						   flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1	/* 32bit absolute address */
+#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
+#define R_PPC_ADDR16		3	/* 16bit absolute address */
+#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
+#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10	/* PC relative 26 bit */
+#define R_PPC_REL14		11	/* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+
+/* PowerPC relocations defined for the TLS access ABI.  */
+#define R_PPC_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC_DTPMOD32		68 /* word32	(sym+add)@dtpmod */
+#define R_PPC_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC_TPREL32		73 /* word32	(sym+add)@tprel */
+#define R_PPC_DTPREL16		74 /* half16*	(sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32		78 /* word32	(sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16	87 /* half16*	(sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO	88 /* half16	(sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16	91 /* half16*	(sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO	92 /* half16*	(sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got@dtprel@ha */
+
+/* Keep this the last entry.  */
+#define R_PPC_NUM		95
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109	/* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116	/* 16 bit relative offset in SDA */
+
+/* Diab tool relocations.  */
+#define R_PPC_DIAB_SDA21_LO	180	/* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI	181	/* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA	182	/* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO	183	/* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
+
+/* GNU relocs used in PIC code sequences.  */
+#define R_PPC_REL16		249	/* word32   (sym-.) */
+#define R_PPC_REL16_LO		250	/* half16   (sym-.)@l */
+#define R_PPC_REL16_HI		251	/* half16   (sym-.)@h */
+#define R_PPC_REL16_HA		252	/* half16   (sym-.)@ha */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16		255
+
+/* PowerPC specific values for the Dyn d_tag field.  */
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_NUM		1
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE		R_PPC_NONE
+#define R_PPC64_ADDR32		R_PPC_ADDR32 /* 32bit absolute address */
+#define R_PPC64_ADDR24		R_PPC_ADDR24 /* 26bit address, word aligned */
+#define R_PPC64_ADDR16		R_PPC_ADDR16 /* 16bit absolute address */
+#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO	/* lower 16bits of address */
+#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI	/* high 16bits of address. */
+#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+#define R_PPC64_ADDR14		R_PPC_ADDR14 /* 16bit address, word aligned */
+#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24		R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
+#define R_PPC64_REL14		R_PPC_REL14 /* PC relative 16 bit */
+#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16		R_PPC_GOT16
+#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
+
+#define R_PPC64_COPY		R_PPC_COPY
+#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE	R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32		R_PPC_UADDR32
+#define R_PPC64_UADDR16		R_PPC_UADDR16
+#define R_PPC64_REL32		R_PPC_REL32
+#define R_PPC64_PLT32		R_PPC_PLT32
+#define R_PPC64_PLTREL32	R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF		R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30		37 /* word30 (S + A - P) >> 2 */
+#define R_PPC64_ADDR64		38 /* doubleword64 S + A */
+#define R_PPC64_ADDR16_HIGHER	39 /* half16 #higher(S + A) */
+#define R_PPC64_ADDR16_HIGHERA	40 /* half16 #highera(S + A) */
+#define R_PPC64_ADDR16_HIGHEST	41 /* half16 #highest(S + A) */
+#define R_PPC64_ADDR16_HIGHESTA	42 /* half16 #highesta(S + A) */
+#define R_PPC64_UADDR64		43 /* doubleword64 S + A */
+#define R_PPC64_REL64		44 /* doubleword64 S + A - P */
+#define R_PPC64_PLT64		45 /* doubleword64 L + A */
+#define R_PPC64_PLTREL64	46 /* doubleword64 L + A - P */
+#define R_PPC64_TOC16		47 /* half16* S + A - .TOC */
+#define R_PPC64_TOC16_LO	48 /* half16 #lo(S + A - .TOC.) */
+#define R_PPC64_TOC16_HI	49 /* half16 #hi(S + A - .TOC.) */
+#define R_PPC64_TOC16_HA	50 /* half16 #ha(S + A - .TOC.) */
+#define R_PPC64_TOC		51 /* doubleword64 .TOC */
+#define R_PPC64_PLTGOT16	52 /* half16* M + A */
+#define R_PPC64_PLTGOT16_LO	53 /* half16 #lo(M + A) */
+#define R_PPC64_PLTGOT16_HI	54 /* half16 #hi(M + A) */
+#define R_PPC64_PLTGOT16_HA	55 /* half16 #ha(M + A) */
+
+#define R_PPC64_ADDR16_DS	56 /* half16ds* (S + A) >> 2 */
+#define R_PPC64_ADDR16_LO_DS	57 /* half16ds  #lo(S + A) >> 2 */
+#define R_PPC64_GOT16_DS	58 /* half16ds* (G + A) >> 2 */
+#define R_PPC64_GOT16_LO_DS	59 /* half16ds  #lo(G + A) >> 2 */
+#define R_PPC64_PLT16_LO_DS	60 /* half16ds  #lo(L + A) >> 2 */
+#define R_PPC64_SECTOFF_DS	61 /* half16ds* (R + A) >> 2 */
+#define R_PPC64_SECTOFF_LO_DS	62 /* half16ds  #lo(R + A) >> 2 */
+#define R_PPC64_TOC16_DS	63 /* half16ds* (S + A - .TOC.) >> 2 */
+#define R_PPC64_TOC16_LO_DS	64 /* half16ds  #lo(S + A - .TOC.) >> 2 */
+#define R_PPC64_PLTGOT16_DS	65 /* half16ds* (M + A) >> 2 */
+#define R_PPC64_PLTGOT16_LO_DS	66 /* half16ds  #lo(M + A) >> 2 */
+
+/* PowerPC64 relocations defined for the TLS access ABI.  */
+#define R_PPC64_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC64_DTPMOD64	68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC64_TPREL64		73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16	74 /* half16*	(sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64	78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS	87 /* half16ds*	(sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS	91 /* half16ds*	(sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI	93 /* half16	(sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA	94 /* half16	(sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS	95 /* half16ds*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS	96 /* half16ds	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER	97 /* half16	(sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA	98 /* half16	(sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST	99 /* half16	(sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16	(sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS	101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS	102 /* half16ds	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER	103 /* half16	(sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel@highesta */
+
+/* Keep this the last entry.  */
+#define R_PPC64_NUM		107
+
+/* PowerPC64 specific values for the Dyn d_tag field.  */
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_OPD	(DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+#define DT_PPC64_NUM    3
+
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC     0x01
+#define EF_ARM_HASENTRY    0x02
+#define EF_ARM_INTERWORK   0x04
+#define EF_ARM_APCS_26     0x08
+#define EF_ARM_APCS_FLOAT  0x10
+#define EF_ARM_PIC         0x20
+#define EF_ARM_ALIGN8      0x40		/* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI     0x80
+#define EF_ARM_OLD_ABI     0x100
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+/* NB. These conflict with values defined above.  */
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN  0x00000000
+#define EF_ARM_EABI_VER1     0x01000000
+#define EF_ARM_EABI_VER2     0x02000000
+
+/* Additional symbol types for Thumb */
+#define STT_ARM_TFUNC      0xd
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
+#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
+					   in the input to a link step */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB          0x10000000   /* Segment contains the location
+					   addressed by the static base */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_ARM_EXIDX	0x70000001	/* .ARM.exidx segment */
+
+/* ARM relocs.  */
+
+#define R_ARM_NONE		0	/* No reloc */
+#define R_ARM_PC24		1	/* PC relative 26 bit branch */
+#define R_ARM_ABS32		2	/* Direct 32 bit  */
+#define R_ARM_REL32		3	/* PC relative 32 bit */
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5	/* Direct 16 bit */
+#define R_ARM_ABS12		6	/* Direct 12 bit */
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8	/* Direct 8 bit */
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+#define R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
+#define R_ARM_COPY		20	/* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT		21	/* Create GOT entry */
+#define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
+#define R_ARM_RELATIVE		23	/* Adjust by program base */
+#define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
+#define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32		26	/* 32 bit GOT entry */
+#define R_ARM_PLT32		27	/* 32 bit PLT address */
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_LDR_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102	/* thumb unconditional branch */
+#define R_ARM_THM_PC9		103	/* thumb conditional branch */
+#define R_ARM_TLS_GD32		104	/* PC-rel 32 bit for global dynamic
+					   thread local data */
+#define R_ARM_TLS_LDM32		105	/* PC-rel 32 bit for local dynamic
+					   thread local data */
+#define R_ARM_TLS_LDO32		106	/* 32 bit offset relative to TLS
+					   block */
+#define R_ARM_TLS_IE32		107	/* PC-rel 32 bit for GOT entry of
+					   static TLS block offset */
+#define R_ARM_TLS_LE32		108	/* 32 bit offset relative to static
+					   TLS block */
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+/* Keep this the last entry.  */
+#define R_ARM_NUM		256
+
+/* IA-64 specific declarations.  */
+
+/* Processor specific flags for the Ehdr e_flags field.  */
+#define EF_IA_64_MASKOS		0x0000000f	/* os-specific flags */
+#define EF_IA_64_ABI64		0x00000010	/* 64-bit ABI */
+#define EF_IA_64_ARCH		0xff000000	/* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)	/* arch extension bits */
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)	/* ia64 unwind bits */
+#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
+
+/* Processor specific flags for the Phdr p_flags field.  */
+#define PF_IA_64_NORECOV	0x80000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field.  */
+#define SHF_IA_64_SHORT		0x10000000	/* section near gp */
+#define SHF_IA_64_NORECOV	0x20000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field.  */
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+/* IA-64 relocations.  */
+#define R_IA64_NONE		0x00	/* none */
+#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
+#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
+#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22		0x2a	/* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I		0x2b	/* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB	0x2c	/* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB	0x2d	/* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22		0x32	/* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I		0x43	/* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B		0x48	/* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B		0x49	/* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB	0x54	/* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB	0x55	/* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB	0x56	/* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB	0x57	/* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
+#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
+#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
+#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
+#define R_IA64_LTV32MSB		0x74	/* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB		0x75	/* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB		0x76	/* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB		0x77	/* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI	0x79	/* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22		0x7a	/* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I		0x7b	/* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY		0x84	/* copy relocation */
+#define R_IA64_SUB		0x85	/* Addend and symbol difference */
+#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
+#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */
+#define R_IA64_TPREL14		0x91	/* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22		0x92	/* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I		0x93	/* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB	0x96	/* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB	0x97	/* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22	0x9a	/* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB	0xa6	/* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB	0xa7	/* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22	0xaa	/* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14		0xb1	/* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22		0xb2	/* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I	0xb3	/* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB	0xb4	/* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB	0xb5	/* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB	0xb6	/* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB	0xb7	/* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22	0xba	/* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* SH relocs.  */
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+/* Keep this the last entry.  */
+#define	R_SH_NUM		256
+
+/* Additional s390 relocs */
+
+#define R_390_NONE		0	/* No reloc.  */
+#define R_390_8			1	/* Direct 8 bit.  */
+#define R_390_12		2	/* Direct 12 bit.  */
+#define R_390_16		3	/* Direct 16 bit.  */
+#define R_390_32		4	/* Direct 32 bit.  */
+#define R_390_PC32		5	/* PC relative 32 bit.	*/
+#define R_390_GOT12		6	/* 12 bit GOT offset.  */
+#define R_390_GOT32		7	/* 32 bit GOT offset.  */
+#define R_390_PLT32		8	/* 32 bit PC relative PLT address.  */
+#define R_390_COPY		9	/* Copy symbol at runtime.  */
+#define R_390_GLOB_DAT		10	/* Create GOT entry.  */
+#define R_390_JMP_SLOT		11	/* Create PLT entry.  */
+#define R_390_RELATIVE		12	/* Adjust by program base.  */
+#define R_390_GOTOFF32		13	/* 32 bit offset to GOT.	 */
+#define R_390_GOTPC		14	/* 32 bit PC relative offset to GOT.  */
+#define R_390_GOT16		15	/* 16 bit GOT offset.  */
+#define R_390_PC16		16	/* PC relative 16 bit.	*/
+#define R_390_PC16DBL		17	/* PC relative 16 bit shifted by 1.  */
+#define R_390_PLT16DBL		18	/* 16 bit PC rel. PLT shifted by 1.  */
+#define R_390_PC32DBL		19	/* PC relative 32 bit shifted by 1.  */
+#define R_390_PLT32DBL		20	/* 32 bit PC rel. PLT shifted by 1.  */
+#define R_390_GOTPCDBL		21	/* 32 bit PC rel. GOT shifted by 1.  */
+#define R_390_64		22	/* Direct 64 bit.  */
+#define R_390_PC64		23	/* PC relative 64 bit.	*/
+#define R_390_GOT64		24	/* 64 bit GOT offset.  */
+#define R_390_PLT64		25	/* 64 bit PC relative PLT address.  */
+#define R_390_GOTENT		26	/* 32 bit PC rel. to GOT entry >> 1. */
+#define R_390_GOTOFF16		27	/* 16 bit offset to GOT. */
+#define R_390_GOTOFF64		28	/* 64 bit offset to GOT. */
+#define R_390_GOTPLT12		29	/* 12 bit offset to jump slot.	*/
+#define R_390_GOTPLT16		30	/* 16 bit offset to jump slot.	*/
+#define R_390_GOTPLT32		31	/* 32 bit offset to jump slot.	*/
+#define R_390_GOTPLT64		32	/* 64 bit offset to jump slot.	*/
+#define R_390_GOTPLTENT		33	/* 32 bit rel. offset to jump slot.  */
+#define R_390_PLTOFF16		34	/* 16 bit offset from GOT to PLT. */
+#define R_390_PLTOFF32		35	/* 32 bit offset from GOT to PLT. */
+#define R_390_PLTOFF64		36	/* 16 bit offset from GOT to PLT. */
+#define R_390_TLS_LOAD		37	/* Tag for load insn in TLS code.  */
+#define R_390_TLS_GDCALL	38	/* Tag for function call in general
+					   dynamic TLS code. */
+#define R_390_TLS_LDCALL	39	/* Tag for function call in local
+					   dynamic TLS code. */
+#define R_390_TLS_GD32		40	/* Direct 32 bit for general dynamic
+					   thread local data.  */
+#define R_390_TLS_GD64		41	/* Direct 64 bit for general dynamic
+					  thread local data.  */
+#define R_390_TLS_GOTIE12	42	/* 12 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE32	43	/* 32 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE64	44	/* 64 bit GOT offset for static TLS
+					   block offset. */
+#define R_390_TLS_LDM32		45	/* Direct 32 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_LDM64		46	/* Direct 64 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_IE32		47	/* 32 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IE64		48	/* 64 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IEENT		49	/* 32 bit rel. offset to GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_LE32		50	/* 32 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LE64		51	/* 64 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LDO32		52	/* 32 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_LDO64		53	/* 64 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_DTPMOD	54	/* ID of module containing symbol.  */
+#define R_390_TLS_DTPOFF	55	/* Offset in TLS block.	 */
+#define R_390_TLS_TPOFF		56	/* Negated offset in static TLS
+					   block.  */
+#define R_390_20		57	/* Direct 20 bit.  */
+#define R_390_GOT20		58	/* 20 bit GOT offset.  */
+#define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
+#define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
+					   block offset.  */
+/* Keep this the last entry.  */
+#define R_390_NUM		61
+
+
+/* CRIS relocations.  */
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
+
+/* AMD x86-64 relocations.  */
+#define R_X86_64_NONE		0	/* No reloc */
+#define R_X86_64_64		1	/* Direct 64 bit  */
+#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
+#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
+#define R_X86_64_PLT32		4	/* 32 bit PLT address */
+#define R_X86_64_COPY		5	/* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
+#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
+#define R_X86_64_RELATIVE	8	/* Adjust by program base */
+#define R_X86_64_GOTPCREL	9	/* 32 bit signed PC relative
+					   offset to GOT */
+#define R_X86_64_32		10	/* Direct 32 bit zero extended */
+#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
+#define R_X86_64_16		12	/* Direct 16 bit zero extended */
+#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
+#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
+#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
+#define R_X86_64_DTPOFF64	17	/* Offset in module's TLS block */
+#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */
+#define R_X86_64_TLSGD		19	/* 32 bit signed PC relative offset
+					   to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD		20	/* 32 bit signed PC relative offset
+					   to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
+#define R_X86_64_GOTTPOFF	22	/* 32 bit signed PC relative offset
+					   to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
+
+#define R_X86_64_NUM		24
+
+
+/* AM33 relocations.  */
+#define R_MN10300_NONE		0	/* No reloc.  */
+#define R_MN10300_32		1	/* Direct 32 bit.  */
+#define R_MN10300_16		2	/* Direct 16 bit.  */
+#define R_MN10300_8		3	/* Direct 8 bit.  */
+#define R_MN10300_PCREL32	4	/* PC-relative 32-bit.  */
+#define R_MN10300_PCREL16	5	/* PC-relative 16-bit signed.  */
+#define R_MN10300_PCREL8	6	/* PC-relative 8-bit signed.  */
+#define R_MN10300_GNU_VTINHERIT	7	/* Ancient C++ vtable garbage... */
+#define R_MN10300_GNU_VTENTRY	8	/* ... collection annotation.  */
+#define R_MN10300_24		9	/* Direct 24 bit.  */
+#define R_MN10300_GOTPC32	10	/* 32-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTPC16	11	/* 16-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTOFF32	12	/* 32-bit offset from GOT.  */
+#define R_MN10300_GOTOFF24	13	/* 24-bit offset from GOT.  */
+#define R_MN10300_GOTOFF16	14	/* 16-bit offset from GOT.  */
+#define R_MN10300_PLT32		15	/* 32-bit PCrel to PLT entry.  */
+#define R_MN10300_PLT16		16	/* 16-bit PCrel to PLT entry.  */
+#define R_MN10300_GOT32		17	/* 32-bit offset to GOT entry.  */
+#define R_MN10300_GOT24		18	/* 24-bit offset to GOT entry.  */
+#define R_MN10300_GOT16		19	/* 16-bit offset to GOT entry.  */
+#define R_MN10300_COPY		20	/* Copy symbol at runtime.  */
+#define R_MN10300_GLOB_DAT	21	/* Create GOT entry.  */
+#define R_MN10300_JMP_SLOT	22	/* Create PLT entry.  */
+#define R_MN10300_RELATIVE	23	/* Adjust by program base.  */
+
+#define R_MN10300_NUM		24
+
+
+/* M32R relocs.  */
+#define R_M32R_NONE		0	/* No reloc. */
+#define R_M32R_16		1	/* Direct 16 bit. */
+#define R_M32R_32		2	/* Direct 32 bit. */
+#define R_M32R_24		3	/* Direct 24 bit. */
+#define R_M32R_10_PCREL		4	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL		5	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL		6	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO		7	/* High 16 bit with unsigned low. */
+#define R_M32R_HI16_SLO		8	/* High 16 bit with signed low. */
+#define R_M32R_LO16		9	/* Low 16 bit. */
+#define R_M32R_SDA16		10	/* 16 bit offset in SDA. */
+#define R_M32R_GNU_VTINHERIT	11
+#define R_M32R_GNU_VTENTRY	12
+/* M32R relocs use SHT_RELA.  */
+#define R_M32R_16_RELA		33	/* Direct 16 bit. */
+#define R_M32R_32_RELA		34	/* Direct 32 bit. */
+#define R_M32R_24_RELA		35	/* Direct 24 bit. */
+#define R_M32R_10_PCREL_RELA	36	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL_RELA	37	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL_RELA	38	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO_RELA	39	/* High 16 bit with unsigned low */
+#define R_M32R_HI16_SLO_RELA	40	/* High 16 bit with signed low */
+#define R_M32R_LO16_RELA	41	/* Low 16 bit */
+#define R_M32R_SDA16_RELA	42	/* 16 bit offset in SDA */
+#define R_M32R_RELA_GNU_VTINHERIT	43
+#define R_M32R_RELA_GNU_VTENTRY	44
+#define R_M32R_REL32		45	/* PC relative 32 bit.  */
+
+#define R_M32R_GOT24		48	/* 24 bit GOT entry */
+#define R_M32R_26_PLTREL	49	/* 26 bit PC relative to PLT shifted */
+#define R_M32R_COPY		50	/* Copy symbol at runtime */
+#define R_M32R_GLOB_DAT		51	/* Create GOT entry */
+#define R_M32R_JMP_SLOT		52	/* Create PLT entry */
+#define R_M32R_RELATIVE		53	/* Adjust by program base */
+#define R_M32R_GOTOFF		54	/* 24 bit offset to GOT */
+#define R_M32R_GOTPC24		55	/* 24 bit PC relative offset to GOT */
+#define R_M32R_GOT16_HI_ULO	56	/* High 16 bit GOT entry with unsigned
+					   low */
+#define R_M32R_GOT16_HI_SLO	57	/* High 16 bit GOT entry with signed
+					   low */
+#define R_M32R_GOT16_LO		58	/* Low 16 bit GOT entry */
+#define R_M32R_GOTPC_HI_ULO	59	/* High 16 bit PC relative offset to
+					   GOT with unsigned low */
+#define R_M32R_GOTPC_HI_SLO	60	/* High 16 bit PC relative offset to
+					   GOT with signed low */
+#define R_M32R_GOTPC_LO		61	/* Low 16 bit PC relative offset to
+					   GOT */
+#define R_M32R_GOTOFF_HI_ULO	62	/* High 16 bit offset to GOT
+					   with unsigned low */
+#define R_M32R_GOTOFF_HI_SLO	63	/* High 16 bit offset to GOT
+					   with signed low */
+#define R_M32R_GOTOFF_LO	64	/* Low 16 bit offset to GOT */
+#define R_M32R_NUM		256	/* Keep this the last entry. */
+
+#endif	/* elf.h */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_common/io.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_common/io.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_common/io.h	(revision 283)
@@ -0,0 +1,64 @@
+/**
+ * \file	io.h
+ * \date	5 September 2012
+ * \author	Cesar Fuguet
+ *
+ * Utility functions to write or read memory mapped hardware registers
+ */
+#ifndef IO_H
+#define IO_H
+
+/**
+ * Read an 32 bits memory mapped hardware register
+ */
+static inline unsigned int ioread32(void * addr)
+{
+	return *(volatile unsigned int *) addr;
+}
+
+/**
+ * Read an 16 bits memory mapped hardware register
+ */
+static inline unsigned short ioread16(void * addr)
+{
+	return *(volatile unsigned short *) addr;
+}
+
+/**
+ * Read an 8 bits memory mapped hardware register
+ */
+static inline unsigned char ioread8(void * addr)
+{
+	return *(volatile unsigned char *) addr;
+}
+
+/**
+ * Write an 32 bits memory mapped hardware register
+ */
+static inline void iowrite32(void * addr, unsigned int value)
+{
+	*(volatile unsigned int *) addr = value;
+	asm volatile("sync");
+}
+
+/**
+ * Write an 16 bits memory mapped hardware register
+ */
+static inline void iowrite16(void * addr, unsigned short value)
+{
+	*(volatile unsigned short *) addr = value;
+	asm volatile("sync");
+}
+
+/**
+ * Write an 8 bits memory mapped hardware register
+ */
+static inline void iowrite8(void * addr, unsigned char value)
+{
+	*(volatile unsigned char *) addr = value;
+	asm volatile("sync");
+}
+
+#undef in_reset
+
+#endif
Index: /branch/giet_vm_ioc_drivers/giet_common/mips32_registers.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_common/mips32_registers.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_common/mips32_registers.h	(revision 283)
@@ -0,0 +1,90 @@
+/********************************************************************************/
+/*    File : mips32_registers.h                        */
+/*    Author : Alain Greiner                            */
+/*    Date : 26/03/2012                            */
+/********************************************************************************/
+/*     We define mnemonics for MIPS32 registers                          */
+/********************************************************************************/
+
+#ifndef _MIPS32_REGISTER_H
+#define _MIPS32_REGISTER_H
+
+/* processor registers */
+
+#define zero  $0
+#define at    $1
+#define v0    $2
+#define v1    $3
+#define a0    $4
+#define a1    $5
+#define a2    $6
+#define a3    $7
+#define t0    $8
+#define t1    $9
+#define t2    $10
+#define t3    $11
+#define t4    $12
+#define t5    $13
+#define t6    $14
+#define t7    $15
+#define s0    $16
+#define s1    $17
+#define s2    $18
+#define s3    $19
+#define s4    $20
+#define s5    $21
+#define s6    $22
+#define s7    $23
+#define t8    $24
+#define t9    $25
+#define k0    $26
+#define k1    $27
+#define gp    $28
+#define sp    $29
+#define fp    $30
+#define ra    $31
+
+/* CP0 registers */
+
+#define CP0_BVAR       $8
+#define CP0_TIME       $9
+#define CP0_SR         $12
+#define CP0_CR         $13
+#define CP0_EPC        $14
+#define CP0_PROCID     $15,1
+#define CP0_SCHED      $4,2
+
+/* CP2 registers */
+
+#define CP2_PTPR             $0 
+#define CP2_MODE             $1
+#define CP2_ICACHE_FLUSH     $2
+#define CP2_DCACHE_FLUSH     $3
+#define CP2_ITLB_INVAL       $4 
+#define CP2_DTLB_INVAL       $5 
+#define CP2_ICACHE_INVAL     $6 
+#define CP2_DCACHE_INVAL     $7
+#define CP2_ICACHE_PREFETCH  $8 
+#define CP2_DCACHE_PREFETCH  $9 
+#define CP2_SYNC             $10 
+#define CP2_IETR             $11 
+#define CP2_DETR             $12 
+#define CP2_IBVAR            $13
+#define CP2_DBVAR            $14
+#define CP2_PARAMS           $15 
+#define CP2_RELEASE          $16 
+#define CP2_DATA_LO          $17     
+#define CP2_DATA_HI          $18         
+#define CP2_ICACHE_INVAL_PA  $19         
+#define CP2_DCACHE_INVAL_PA  $20 
+#define CP2_PADDR_EXT        $24
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_common/utils.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_common/utils.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_common/utils.c	(revision 283)
@@ -0,0 +1,689 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : utils.c
+// Date     : 18/10/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The utils.c and utils.h files are part of the GIET-VM nano-kernel.
+// They define more or less the GIET-VM HAL (Hardware Abstraction Layer),
+// and contains various utility functions, that can be used by both the 
+// boot code and the kernel code.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <mapping_info.h>
+#include <utils.h>
+#include <ctx_handler.h>
+#include <tty_driver.h>
+#include <stdarg.h>
+
+// This global variable is allocated in the boot.c file or in kernel_init.c file
+extern static_scheduler_t* _schedulers[X_SIZE * Y_SIZE * NB_PROCS_MAX];
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function implements a pseudo-random delay.
+// The val argument define approximately an exponentially increasing mean delay,
+// and should not be larger than 32.
+///////////////////////////////////////////////////////////////////////////////////
+inline void _random_wait( unsigned int val )
+{
+    unsigned int mask  = (1<<(val&0x1F))-1;
+    unsigned int delay = (_get_proctime() ^ (_get_procid()<<4)) & mask;
+    asm volatile( "move  $3,   %0                 \n"
+                  "loop_nic_completed:            \n"
+                  "addi  $3,   $3, -1             \n"
+                  "bnez  $3,   loop_nic_completed \n"
+                  "nop                            \n"
+                  :
+                  : "r" (delay)
+                  : "$3" ); 
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Copy a source memory buffer content to a dest memory buffer (size bytes)
+// Code taken from MutekH.
+///////////////////////////////////////////////////////////////////////////////////
+inline void* _memcpy( void*        dest,     // dest buffer vbase
+                      const void*  source,   // source buffer vbase
+                      unsigned int size )    // bytes
+{
+    unsigned int*       dst = dest;
+    const unsigned int* src = source;
+
+    // word-by-word copy
+    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;
+
+    /* byte-by-byte copy */
+    while (size--) 
+    {
+        *cdst++ = *csrc++;
+    }
+    return dest;
+}
+//////////////////////////////////////////////////////////////////////////////////
+// Fill a byte string with a byte value.
+//////////////////////////////////////////////////////////////////////////////////
+inline void * _memset( void*        dst, 
+                       int          value, 
+                       unsigned int count ) 
+{
+    char * a = (char *) dst;
+    while (count--) 
+    {
+        *a++ = (char)value;
+    }
+    return dst;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// Processor suicide: infinite loop  
+//////////////////////////////////////////////////////////////////////////////////
+inline void _exit() 
+{
+    while (1) { asm volatile ("nop"); }
+}
+///////////////////////////////////////////////////////////////////////////////////
+//         CP0 and CP2 registers access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// Returns the value contained in CP0 SCHED register
+// (virtual base address of the processor scheduler).
+///////////////////////////////////////////////////////////////////////////////////
+inline unsigned int _get_sched() 
+{
+    unsigned int ret;
+    asm volatile("mfc0      %0,     $4, 2\n" : "=r"(ret) );
+    return ret;
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Returns PTPR register content.
+///////////////////////////////////////////////////////////////////////////////////
+inline unsigned int _get_mmu_ptpr() 
+{
+    unsigned int ret;
+    asm volatile("mfc2      %0,     $0" : "=r"(ret));
+    return ret;
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Returns EPC register content.
+///////////////////////////////////////////////////////////////////////////////////
+inline unsigned int _get_epc() 
+{
+    unsigned int ret;
+    asm volatile("mfc0      %0,     $14" : "=r"(ret));
+    return ret;
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Returns BVAR register content.
+///////////////////////////////////////////////////////////////////////////////////
+inline unsigned int _get_bvar() 
+{
+    unsigned int ret;
+    asm volatile("mfc0      %0,     $8" : "=r"(ret));
+    return ret;
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Returns CR register content.
+///////////////////////////////////////////////////////////////////////////////////
+inline unsigned int _get_cr() 
+{
+    unsigned int ret;
+    asm volatile("mfc0      %0,     $13" : "=r"(ret));
+    return ret;
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Returns SR register content
+///////////////////////////////////////////////////////////////////////////////////
+inline unsigned int _get_sr() 
+{
+    unsigned int ret;
+    asm volatile("mfc0      %0,     $12" : "=r"(ret));
+    return ret;
+}
+//////////////////////////////////////////////////////////////////////////////
+// This function set a new value for the CP0 status register.
+//////////////////////////////////////////////////////////////////////////////
+inline void _set_sr(unsigned int val) 
+{
+    asm volatile("mtc0      %0,     $12" ::"r" (val));
+}
+//////////////////////////////////////////////////////////////////////////////////
+// Returns processor index
+//////////////////////////////////////////////////////////////////////////////////
+inline unsigned int _get_procid() 
+{
+    unsigned int ret;
+    asm volatile ("mfc0     %0,     $15, 1":"=r" (ret));
+    return (ret & 0x3FF);
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Returns local time (32 bits value)
+// boot_proctime() 
+///////////////////////////////////////////////////////////////////////////////////
+inline unsigned int _get_proctime() 
+{
+    unsigned int ret;
+    asm volatile ("mfc0     %0,     $9":"=r" (ret));
+    return ret;
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Returns index of the currently running task from the sheduler.
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _get_proc_task_id() 
+{
+    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
+    return (unsigned int) (psched->current);
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Disables IRQs
+///////////////////////////////////////////////////////////////////////////////////
+inline void _it_disable() 
+{
+    asm volatile(
+            "li      $3,        0xFFFFFFFE    \n"
+            "mfc0    $4,        $12           \n"
+            "and     $3,        $3, $4        \n"
+            "mtc0    $3,        $12           \n"
+            ::: "$3", "$4");
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Enables IRQs
+///////////////////////////////////////////////////////////////////////////////////
+inline void _it_enable() 
+{
+    asm volatile(
+            "li      $3,        0x00000001    \n"
+            "mfc0    $4,        $12           \n"
+            "or      $3,        $3, $4        \n"
+            "mtc0    $3,        $12           \n"
+            ::: "$3", "$4");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This function set a new value for the MMU PTPR register.
+//////////////////////////////////////////////////////////////////////////////
+inline void _set_mmu_ptpr(unsigned int val) 
+{
+    asm volatile ("mtc2     %0,     $0"::"r" (val));
+}
+//////////////////////////////////////////////////////////////////////////////
+// This function set a new value for the MMU MODE register.
+//////////////////////////////////////////////////////////////////////////////
+inline void _set_mmu_mode(unsigned int val) 
+{
+    asm volatile ("mtc2     %0,     $1"::"r" (val));
+}
+//////////////////////////////////////////////////////////////////////////////
+// This function set a new value in CP0 SCHED register.
+// (virtual base address of the processor scheduler).
+//////////////////////////////////////////////////////////////////////////////
+inline void _set_sched(unsigned int val) 
+{
+    asm volatile ("mtc0     %0,     $4, 2"::"r" (val));
+}
+
+////////////////////////////////////////////////////////////////////////////
+//          Physical addressing related functions
+////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////
+// This function makes a physical read access to a 32 bits word in memory, 
+// after a temporary DTLB de-activation and paddr extension.
+////////////////////////////////////////////////////////////////////////////
+inline unsigned int _physical_read( unsigned long long paddr ) 
+{
+    unsigned int value;
+    unsigned int lsb = (unsigned int) paddr;
+    unsigned int msb = (unsigned int) (paddr >> 32);
+
+    asm volatile(
+            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
+            "andi   $3,     $2,        0xb     \n"
+            "mtc2   $3,     $1                 \n"     /* DTLB off         */    
+
+            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
+            "lw     %0,     0(%1)              \n"     /* value <= *paddr  */
+            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
+
+            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
+            : "=r" (value)
+            : "r" (lsb), "r" (msb)
+            : "$2", "$3");
+    return value;
+}
+////////////////////////////////////////////////////////////////////////////
+// This function makes a physical write access to a 32 bits word in memory, 
+// after a temporary DTLB de-activation and paddr extension.
+////////////////////////////////////////////////////////////////////////////
+inline void _physical_write( unsigned long long paddr, 
+                      unsigned int       value ) 
+{
+    unsigned int lsb = (unsigned int)paddr;
+    unsigned int msb = (unsigned int)(paddr >> 32);
+
+    asm volatile(
+            "mfc2   $2,     $1                 \n"     /* $2 <= MMU_MODE   */
+            "andi   $3,     $2,        0xb     \n"
+            "mtc2   $3,     $1                 \n"     /* DTLB off         */    
+
+            "mtc2   %2,     $24                \n"     /* PADDR_EXT <= msb */   
+            "sw     %0,     0(%1)              \n"     /* *paddr <= value  */
+            "mtc2   $0,     $24                \n"     /* PADDR_EXT <= 0   */   
+
+            "mtc2   $2,     $1                 \n"     /* restore MMU_MODE */
+            :
+            : "r" (value), "r" (lsb), "r" (msb)
+            : "$2", "$3");
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Locks access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// Takes a lock with an ll/sc atomic access.
+// A pseudo random delay is introduced before retry in case of miss
+// (delay average value = 100 cycles)
+///////////////////////////////////////////////////////////////////////////////////
+inline void _get_lock(unsigned int * plock) 
+{
+    register unsigned int delay = ( _get_proctime() ^ _get_procid() << 4) & 0xFF;
+
+    if (delay == 0) delay++;
+
+    asm volatile (
+            "_lock_llsc:             \n"
+            "ll   $2,    0(%0)       \n" /* $2 <= _ioc_lock current value */
+            "bnez $2,    _lock_delay \n" /* delay if _ioc_lock already taken */
+            "li   $3,    1           \n" /* $3 <= argument for sc */
+            "sc   $3,    0(%0)       \n" /* try to set _ioc_lock */
+            "bnez $3,    _lock_ok    \n" /* exit if atomic */
+            "_lock_delay:            \n"
+            "move $4,    %1          \n" /* $4 <= delay */
+            "_lock_loop:             \n"
+            "addi $4,    $4,    -1   \n" /* $4 <= $4 - 1 */
+            "bnez $4,    _lock_loop  \n" /* test end delay */
+            "nop                     \n"
+            "j           _lock_llsc  \n" /* retry */
+            "nop                     \n"
+            "_lock_ok:               \n"
+            :
+            :"r"(plock), "r"(delay)
+            :"$2", "$3", "$4");
+}
+///////////////////////////////////////////////////////////////////////////////////
+// Release a previouly taken lock.
+///////////////////////////////////////////////////////////////////////////////////
+inline void _release_lock(unsigned int * plock) 
+{
+    asm volatile ( "sync\n" ); // necessary because of the TSAR consistency model 
+    *plock = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Display a string on TTY0 / used for system code debug and log.
+// It does not use the TTY driver, but uses the seg_tty_base variable...
+///////////////////////////////////////////////////////////////////////////////////
+void _puts(char * buffer) 
+{
+    unsigned int n;
+    for (n = 0; n < 1000; n++) 
+    {
+        if (buffer[n] == 0)  break; 
+    }
+    _tty_write( buffer, n, 0 );   // last argument is TTY channel
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+//           Access functions to system terminal TTY0
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// Display a 32 bits unsigned int as an hexadecimal string on TTY0 
+///////////////////////////////////////////////////////////////////////////////////
+void _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;
+    }
+    _puts(buf);
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Display a 64 bits unsigned long as an hexadecimal string on TTY0 
+///////////////////////////////////////////////////////////////////////////////////
+void _putl(unsigned long long val)
+{
+    static const char HexaTab[] = "0123456789ABCDEF";
+    char buf[19];
+    unsigned int c;
+
+    buf[0] = '0';
+    buf[1] = 'x';
+    buf[18] = 0;
+
+    for (c = 0; c < 16; c++) 
+    { 
+        buf[17 - c] = HexaTab[(unsigned int)val & 0xF];
+        val = val >> 4;
+    }
+    _puts(buf);
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Display a 32 bits unsigned int as a decimal string on TTY0
+///////////////////////////////////////////////////////////////////////////////////
+void _putd(unsigned int val) 
+{
+    static const char DecTab[] = "0123456789";
+    char buf[11];
+    unsigned int i;
+    unsigned int first;
+
+    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;
+    }
+    _puts(&buf[first]);
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Compare two strings s1 & s2 (no more than n characters)
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _strncmp( const char * s1, 
+                       const char * s2, 
+                       unsigned int n ) 
+{
+    unsigned int i;
+    for (i = 0; i < n; i++) 
+    {
+        if (s1[i] != s2[i])  return 1; 
+        if (s1[i] == 0)      break;
+    }
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Copy source string to dest string
+///////////////////////////////////////////////////////////////////////////////////
+char* _strcpy( char* dest, char* source )
+{
+    if (!dest || !source) return dest;
+
+    while (*source)
+        *(dest++) = *(source++);
+
+    return dest;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// Invalidate all data cache lines corresponding to a memory 
+// buffer (identified by an address and a size).
+// TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
+// register, to be more processor independant.
+///////////////////////////////////////////////////////////////////////////////////
+void _dcache_buf_invalidate( const void * buffer, 
+                             unsigned int size) 
+{
+    unsigned int i;
+    unsigned int tmp;
+    unsigned int line_size;
+
+    // compute data cache line size based on config register (bits 12:10)
+    asm volatile(
+                 "mfc0 %0, $16, 1" 
+                 : "=r" (tmp) );
+    tmp = ((tmp >> 10) & 0x7);
+    line_size = 2 << tmp;
+
+    // iterate on cache lines 
+    for (i = 0; i < size; i += line_size) 
+    {
+        asm volatile(
+                " cache %0, %1"
+                : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// This function returns the content of a context slot 
+// for any task identified by the ltid argument (local task index),
+// and the gpid argument (global processor index)
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int _get_task_slot( unsigned int gpid,
+                             unsigned int ltid,
+                             unsigned int slot )
+{
+    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[gpid];
+    return psched->context[ltid][slot];
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// This function updates the content of a context slot 
+// for any task identified by the ltid argument (local task index),
+// and the gpid argument (global processor index)
+////////////////////////////////////////////////////////////////////////////////////
+void _set_task_slot( unsigned int gpid,
+                     unsigned int ltid,
+                     unsigned int slot,
+                     unsigned int value )
+{
+    static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[gpid];
+    psched->context[ltid][slot] = value;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// This function returns the content of a context slot 
+// for the running task (defined by the scheduler current field).
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int _get_context_slot( unsigned int slot )
+{
+    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
+    unsigned int        task_id = psched->current;
+    return psched->context[task_id][slot];
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// This function updates the content of a context slot for the running task.
+////////////////////////////////////////////////////////////////////////////////////
+void _set_context_slot( unsigned int slot,
+                       unsigned int value )
+{
+    static_scheduler_t* psched  = (static_scheduler_t*)_get_sched();
+    unsigned int        task_id = psched->current;
+    psched->context[task_id][slot] = value;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function returns the information associated to a heap (size and vaddr)
+// It uses the global task index (CTX_GTID_ID, unique for each giet task) and the
+// vspace index (CTX_VSID_ID) defined in the task context. 
+///////////////////////////////////////////////////////////////////////////////////
+unsigned int _heap_info( unsigned int* vaddr, 
+                         unsigned int* size ) 
+{
+    mapping_header_t * header  = (mapping_header_t *) (&seg_boot_mapping_base);
+    mapping_task_t * tasks     = _get_task_base(header);
+    mapping_vobj_t * vobjs     = _get_vobj_base(header);
+    mapping_vspace_t * vspaces = _get_vspace_base(header);
+
+    unsigned int taskid        = _get_context_slot(CTX_GTID_ID);
+    unsigned int vspaceid      = _get_context_slot(CTX_VSID_ID);
+
+    int heap_local_vobjid      = tasks[taskid].heap_vobjid;
+    if (heap_local_vobjid != -1) 
+    {
+        unsigned int vobjheapid = heap_local_vobjid + vspaces[vspaceid].vobj_offset;
+        *vaddr                  = vobjs[vobjheapid].vaddr;
+        *size                   = vobjs[vobjheapid].length;
+        return 0;
+    }
+    else 
+    {
+        *vaddr = 0;
+        *size = 0;
+        return 0;
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//      Access functions to mapping_info data structure
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_cluster_t * _get_cluster_base(mapping_header_t * header) 
+{
+    return (mapping_cluster_t *) ((char *) header +
+            MAPPING_HEADER_SIZE);
+}
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_pseg_t * _get_pseg_base(mapping_header_t * header) 
+{
+    return (mapping_pseg_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE);
+}
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_vspace_t * _get_vspace_base(mapping_header_t * header) 
+{
+    return (mapping_vspace_t *)  ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs);
+}
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_vseg_t * _get_vseg_base(mapping_header_t * header)
+{
+    return (mapping_vseg_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces);
+}
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_vobj_t * _get_vobj_base(mapping_header_t * header) 
+{
+    return (mapping_vobj_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VSEG_SIZE * header->vsegs );
+}
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_task_t * _get_task_base(mapping_header_t * header) 
+{
+    return (mapping_task_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs);
+}
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_proc_t *_get_proc_base(mapping_header_t * header) 
+{
+    return (mapping_proc_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_TASK_SIZE * header->tasks);
+}
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_irq_t *_get_irq_base(mapping_header_t * header) 
+{
+    return (mapping_irq_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_TASK_SIZE * header->tasks +
+            MAPPING_PROC_SIZE * header->procs);
+}
+/////////////////////////////////////////////////////////////////////////////
+inline mapping_coproc_t *_get_coproc_base(mapping_header_t * header) 
+{
+    return (mapping_coproc_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_TASK_SIZE * header->tasks +
+            MAPPING_PROC_SIZE * header->procs +
+            MAPPING_IRQ_SIZE * header->irqs);
+}
+///////////////////////////////////////////////////////////////////////////////////
+inline mapping_cp_port_t *_get_cp_port_base(mapping_header_t * header) 
+{
+    return (mapping_cp_port_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_TASK_SIZE * header->tasks +
+            MAPPING_PROC_SIZE * header->procs +
+            MAPPING_IRQ_SIZE * header->irqs +
+            MAPPING_COPROC_SIZE * header->coprocs);
+}
+///////////////////////////////////////////////////////////////////////////////////
+inline mapping_periph_t *_get_periph_base(mapping_header_t * header) 
+{
+    return (mapping_periph_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * X_SIZE * Y_SIZE +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_TASK_SIZE * header->tasks +
+            MAPPING_PROC_SIZE * header->procs +
+            MAPPING_IRQ_SIZE * header->irqs +
+            MAPPING_COPROC_SIZE * header->coprocs +
+            MAPPING_CP_PORT_SIZE * header->cp_ports);
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_common/utils.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_common/utils.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_common/utils.h	(revision 283)
@@ -0,0 +1,209 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : utils.h
+// Date     : 18/10/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The utils.c and utils.h files are part of the GIET-VM nano-kernel.
+// They define more or less the GIET-VM HAL (Hardware Abstraction Layer),
+// and contains various utility functions, that can be used by both the 
+// boot code and the kernel code.
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef GIET_UTILS_H
+#define GIET_UTILS_H
+
+#include <mapping_info.h>
+#include <giet_config.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+// For retrieving base addresses defined in seg.ld file.
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct _ld_symbol_s _ld_symbol_t;
+
+// peripheral base addresses
+extern _ld_symbol_t seg_iob_base;
+extern _ld_symbol_t seg_nic_base;
+extern _ld_symbol_t seg_icu_base;
+extern _ld_symbol_t seg_xcu_base;
+extern _ld_symbol_t seg_tim_base;
+extern _ld_symbol_t seg_tty_base;
+extern _ld_symbol_t seg_gcd_base;
+extern _ld_symbol_t seg_dma_base;
+extern _ld_symbol_t seg_fbf_base;
+extern _ld_symbol_t seg_ioc_base;
+extern _ld_symbol_t seg_mmc_base;
+extern _ld_symbol_t seg_cma_base;
+extern _ld_symbol_t seg_hba_base;
+extern _ld_symbol_t seg_sim_base;
+
+// for replicated peripherals
+extern _ld_symbol_t vseg_cluster_increment;
+
+// boot and kernel segments base addresses & sizes
+extern _ld_symbol_t seg_boot_code_base;
+extern _ld_symbol_t seg_boot_code_size;
+
+extern _ld_symbol_t seg_boot_data_base;
+extern _ld_symbol_t seg_boot_data_size;
+
+extern _ld_symbol_t seg_boot_stack_base;
+extern _ld_symbol_t seg_boot_stack_size;
+
+extern _ld_symbol_t seg_boot_mapping_base;
+extern _ld_symbol_t seg_boot_mapping_size;
+
+extern _ld_symbol_t seg_boot_buffer_base;
+extern _ld_symbol_t seg_boot_buffer_size;
+
+extern _ld_symbol_t seg_kernel_code_base;
+extern _ld_symbol_t seg_kernel_code_size;
+
+extern _ld_symbol_t seg_kernel_data_base;
+extern _ld_symbol_t seg_kernel_data_size;
+
+extern _ld_symbol_t seg_kernel_uncdata_base;
+extern _ld_symbol_t seg_kernel_uncdata_size;
+
+extern _ld_symbol_t seg_kernel_init_base;
+extern _ld_symbol_t seg_kernel_init_size;
+
+
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Memory handling functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern void* _memcpy( void* _dst, 
+                      const void* _src, 
+                      unsigned int size );
+
+extern void* _memset( void* dst, 
+                      int s, 
+                      unsigned int count );
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Suicide function
+///////////////////////////////////////////////////////////////////////////////////
+
+extern void _exit(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Eret function
+///////////////////////////////////////////////////////////////////////////////////
+
+extern void _eret(void);
+
+///////////////////////////////////////////////////////////////////////////////////
+//     CP0 and CP2 registers access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _get_sched(void);
+extern unsigned int _get_mmu_ptpr(void);
+extern unsigned int _get_epc(void);
+extern unsigned int _get_bvar(void);
+extern unsigned int _get_cr(void);
+extern unsigned int _get_sr(void);
+extern unsigned int _get_procid(void);
+extern unsigned int _get_proctime(void);
+extern unsigned int _get_proc_task_id(void);
+
+extern void         _it_disable(void);
+extern void         _it_enable(void);
+
+extern void         _set_mmu_ptpr(unsigned int value);
+extern void         _set_mmu_mode(unsigned int value);
+extern void         _set_sched(unsigned int value);
+extern void         _set_sr(unsigned int value);
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Physical addressing related functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _physical_read(  unsigned long long paddr );
+
+extern void         _physical_write( unsigned long long paddr,
+                                     unsigned int       value );
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Locks access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern void         _get_lock(unsigned int * lock);
+extern void         _release_lock(unsigned int * lock);
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Display functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern void         _puts(char *string);             // display a string
+extern void         _putx(unsigned int val);         // display a 32 bits value (hexa) 
+extern void         _putd(unsigned int val);         // display a 32 bits value (dec)
+extern void         _putl(unsigned long long val);   // display a 64 bits value (hexa)
+
+///////////////////////////////////////////////////////////////////////////////////
+//     string compare functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _strncmp(const char*  s1, 
+                             const char*  s2, 
+                             unsigned int n);
+
+extern char*        _strcpy( char*        dest,
+                             char*        source );
+
+///////////////////////////////////////////////////////////////////////////////////
+//     cache invalidate function
+///////////////////////////////////////////////////////////////////////////////////
+
+extern void  _dcache_buf_invalidate( const void * buffer, 
+                                     unsigned int size );
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Schedulers access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _get_task_slot( unsigned int gpid,
+                                    unsigned int ltid,
+                                    unsigned int slot );
+
+extern void         _set_task_slot( unsigned int gpid,
+                                    unsigned int ltid,
+                                    unsigned int slot,
+                                    unsigned int value );
+
+extern unsigned int _get_context_slot( unsigned int slot );
+
+extern void         _set_context_slot( unsigned int slot,
+                                       unsigned int value );
+
+extern unsigned int _heap_info( unsigned int* vaddr,
+                                unsigned int* size );
+
+///////////////////////////////////////////////////////////////////////////////////
+//     Mapping access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern mapping_cluster_t *  _get_cluster_base(mapping_header_t* header);
+extern mapping_pseg_t *     _get_pseg_base(mapping_header_t* header);
+extern mapping_vspace_t *   _get_vspace_base(mapping_header_t* header);
+extern mapping_vseg_t *     _get_vseg_base(mapping_header_t* header);
+extern mapping_vobj_t *     _get_vobj_base(mapping_header_t* header);
+extern mapping_task_t *     _get_task_base(mapping_header_t* header);
+extern mapping_proc_t *     _get_proc_base(mapping_header_t* header);
+extern mapping_irq_t *      _get_irq_base(mapping_header_t* header);
+extern mapping_coproc_t *   _get_coproc_base(mapping_header_t* header);
+extern mapping_cp_port_t *  _get_cp_port_base(mapping_header_t* header);
+extern mapping_periph_t *   _get_periph_base(mapping_header_t* header);
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_common/vmem.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_common/vmem.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_common/vmem.c	(revision 283)
@@ -0,0 +1,164 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : vmem.c
+// Date     : 01/07/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The vmem.c and vmem.h files are part ot the GIET-VM nano kernel.
+// They contain the kernel data structures and functions used to dynamically
+// handle the paged virtual memory.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <utils.h>
+#include <tty_driver.h>
+#include <vmem.h>
+#include <giet_config.h>
+#include <tty_driver.h>
+
+/////////////////////////////////////////////////////////////////////////////
+//     Global variable : IOMMU page table
+/////////////////////////////////////////////////////////////////////////////
+
+__attribute__((section (".iommu"))) page_table_t _iommu_ptab;
+
+//////////////////////////////////////////////////////////////////////////////
+// _iommu_add_pte2()
+//////////////////////////////////////////////////////////////////////////////
+void _iommu_add_pte2(
+        unsigned int ix1,
+        unsigned int ix2,
+        unsigned int ppn,
+        unsigned int flags) 
+{
+    unsigned int ptba;
+    unsigned int * pt_ppn;
+    unsigned int * pt_flags;
+
+    // get pointer on iommu page table
+    page_table_t * pt = &_iommu_ptab;
+
+    // get ptba and update PT2
+    if ((pt->pt1[ix1] & PTE_V) == 0) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in iommu_add_pte2 function\n");
+        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
+        _putx( ix1 );
+        _puts("\n");
+        _tty_release_lock( 0 );
+        _exit();
+    }
+    else 
+    {
+        ptba = pt->pt1[ix1] << 12;
+        pt_flags = (unsigned int *) (ptba + 8 * ix2);
+        pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4);
+        *pt_flags = flags;
+        *pt_ppn = ppn;
+    }
+} // end _iommu_add_pte2()
+
+
+//////////////////////////////////////////////////////////////////////////////
+// _iommu_inval_pte2()
+//////////////////////////////////////////////////////////////////////////////
+void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) {
+    unsigned int ptba;
+    unsigned int * pt_flags;
+
+    // get pointer on iommu page table
+    page_table_t * pt = &_iommu_ptab;
+
+    // get ptba and inval PTE2
+    if ((pt->pt1[ix1] & PTE_V) == 0)
+    {
+        _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n");
+        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
+        _putx( ix1 );
+        _puts("\n");
+        _exit();
+    }
+    else {
+        ptba = pt->pt1[ix1] << 12;
+        pt_flags = (unsigned int *) (ptba + 8 * ix2);
+        *pt_flags = 0;
+    }   
+} // end _iommu_inval_pte2()
+
+//////////////////////////////////////////////////////////////////////////////
+// This function makes a "vpn" to "ppn" translation, from the page table 
+// defined by the virtual address "pt". The MMU is supposed to be activated.
+// It uses the address extension mechanism for physical addressing.
+// Return 0 if success. Return 1 if PTE1 or PTE2 unmapped.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _v2p_translate( page_table_t*  pt,
+                             unsigned int   vpn,
+                             unsigned int*  ppn,
+                             unsigned int*  flags) 
+{
+    unsigned long long ptba;
+    unsigned long long pte2_paddr;
+
+    register unsigned int pte2_msb;
+    register unsigned int pte2_lsb;
+    register unsigned int flags_value;
+    register unsigned int ppn_value;
+
+    unsigned int ix1 = vpn >> 9;
+    unsigned int ix2 = vpn & 0x1FF;
+
+    // get PTE1
+    unsigned int pte1 = pt->pt1[ix1];
+
+    // check PTE1 mapping
+    if ( (pte1 & PTE_V) == 0 )  return 1;
+
+    // get physical addresses of pte2 (two 32 bits words)
+    ptba       = (unsigned long long) (pt->pt1[ix1] & 0x0FFFFFFF) << 12;
+    pte2_paddr = ptba + 8*ix2;
+    pte2_lsb   = (unsigned int) pte2_paddr;
+    pte2_msb   = (unsigned int) (pte2_paddr >> 32);
+
+    // gets ppn_value and flags_value, after temporary DTLB desactivation
+    asm volatile (
+                "li      $2,     0xFFFFFFFE  \n"     /* Mask for IE bits     */
+                "mfc0    $4,     $12         \n"     /* $4 <= SR             */ 
+                "and     $2,     $2,    $4   \n"
+                "mtc0    $2,     $12         \n"     /* disable Interrupts   */
+
+                "li      $3,     0xB         \n"     
+                "mtc2    $3,     $1          \n"     /* DTLB unactivated     */ 
+
+                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= msb     */
+                "lw      %0,     0(%3)       \n"     /* read flags           */ 
+                "lw      %1,     4(%3)       \n"     /* read ppn             */
+                "mtc2    $0,     $24         \n"     /* PADDR_EXT <= 0       */
+
+                "li      $3,     0xF         \n" 
+                "mtc2    $3,     $1          \n"     /* DTLB activated       */
+
+                "mtc0    $4,     $12         \n"     /* restore SR           */
+                : "=r" (flags_value), "=r" (ppn_value)
+                : "r" (pte2_msb), "r" (pte2_lsb)
+                : "$2","$3","$4");
+
+    // check PTE2 mapping
+    if ( (flags_value & PTE_V) == 0 )  return 1;
+
+    // set return values 
+    *ppn = ppn_value;
+    *flags = flags_value;
+    return 0;
+} // end _v2p_translate()
+
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
+
Index: /branch/giet_vm_ioc_drivers/giet_common/vmem.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_common/vmem.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_common/vmem.h	(revision 283)
@@ -0,0 +1,92 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : vm_handler.h
+// Date     : 01/07/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _VM_HANDLER_H_
+#define _VM_HANDLER_H_
+
+#include <giet_config.h>
+#include <mapping_info.h>
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Page Table sizes definition
+/////////////////////////////////////////////////////////////////////////////////////
+
+#define PT1_SIZE    8192
+#define PT2_SIZE    4096
+
+/////////////////////////////////////////////////////////////////////////////////////
+// PTE flags masks definition 
+/////////////////////////////////////////////////////////////////////////////////////
+
+#define PTE_V  0x80000000
+#define PTE_T  0x40000000
+#define PTE_L  0x20000000
+#define PTE_R  0x10000000
+#define PTE_C  0x08000000
+#define PTE_W  0x04000000
+#define PTE_X  0x02000000
+#define PTE_U  0x01000000
+#define PTE_G  0x00800000
+#define PTE_D  0x00400000
+
+/////////////////////////////////////////////////////////////////////////////////////
+// MMU error codes definition 
+/////////////////////////////////////////////////////////////////////////////////////
+
+#define MMU_ERR_PT1_UNMAPPED         0x001 // Page fault on Table1 (invalid PTE) 
+#define MMU_ERR_PT2_UNMAPPED         0x002 // Page fault on Table 2 (invalid PTE) 
+#define MMU_ERR_PRIVILEGE_VIOLATION  0x004 // Protected access in user mode 
+#define MMU_ERR_WRITE_VIOLATION      0x008 // Write access to a non write page 
+#define MMU_ERR_EXEC_VIOLATION       0x010 // Exec access to a non exec page 
+#define MMU_ERR_UNDEFINED_XTN        0x020 // Undefined external access address 
+#define MMU_ERR_PT1_ILLEGAL_ACCESS   0x040 // Bus Error in Table1 access 
+#define MMU_ERR_PT2_ILLEGAL_ACCESS   0x080 // Bus Error in Table2 access 
+#define MMU_ERR_CACHE_ILLEGAL_ACCESS 0x100 // Bus Error during the cache access 
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Page table structure definition
+/////////////////////////////////////////////////////////////////////////////////////
+typedef struct PageTable 
+{
+    unsigned int pt1[PT1_SIZE / 4];    // PT1 (index is ix1)
+    unsigned int pt2[1][PT2_SIZE / 4]; // PT2s (index is 2*ix2)
+} page_table_t;
+
+
+////////////////////////////////////////////////////////////////////////////////////
+// Global variable
+////////////////////////////////////////////////////////////////////////////////////
+
+extern page_table_t _iommu_ptab;
+
+////////////////////////////////////////////////////////////////////////////////////
+// functions prototypes
+////////////////////////////////////////////////////////////////////////////////////
+
+void _iommu_add_pte2( unsigned int ix1, 
+                      unsigned int ix2, 
+                      unsigned int ppn, 
+                      unsigned int flags );
+
+void _iommu_inval_pte2( unsigned int ix1, 
+                        unsigned int ix2 );
+
+unsigned int _v2p_translate( page_table_t* pt, 
+                             unsigned int  vpn, 
+                             unsigned int* ppn, 
+                             unsigned int* flags );
+
+#endif 
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_config.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_config.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_config.h	(revision 283)
@@ -0,0 +1,49 @@
+/********************************************************************************/
+/*	File : giet_config.h                                                        */
+/*	Author : Alain Greiner                                                      */
+/*	Date : 26/03/2013                                                           */
+/********************************************************************************/
+/* 	Define various configuration parameters for the GIET			            */
+/********************************************************************************/
+
+#ifndef _GIET_VM_CONFIG_H
+#define _GIET_VM_CONFIG_H
+
+/* hardware parameters */
+#include "hard_config.h"
+
+/* Debug parameters */
+
+#define BOOT_DEBUG_MAPPING       0			/* trace map_info checking */
+#define BOOT_DEBUG_PT		     0			/* trace page tables initialisation */
+#define BOOT_DEBUG_VOBJS	     0			/* trace vobjs initialisation */
+#define BOOT_DEBUG_SCHED 	     0			/* trace schedulers initialisation */
+#define BOOT_DEBUG_PERI          0			/* trace peripherals initialisation */
+#define BOOT_DEBUG_ELF           0          /* trace .elf files loading */
+
+#define GIET_DEBUG_INIT		     0			/* trace parallel kernel initialisation */
+
+#define GIET_DEBUG_FAT           0          /* trace fat accesses */ 
+#define GIET_DEBUG_SWITCH	     0			/* trace context switchs  */
+#define GIET_DEBUG_IOC_DRIVER    0          /* trace IOC accesses */
+#define GIET_DEBUG_DMA_DRIVER    0          /* trace DMA accesses */
+#define GIET_DEBUG_FBF_DRIVER    0          /* trace FBF accesses */
+
+#define CONFIG_SRL_VERBOSITY TRACE 
+
+/* software parameters */
+
+#define GIET_IDLE_TASK_PERIOD    10000000   /* Idle Task message period */
+#define GIET_IDLE_TASK_VERBOSITY 1
+
+#define GIET_MONO_TTY            0          /* Only one terminal is used */
+
+#define GIET_MAX_ELF_FILES       20         /* max .elf files loaded by boot-loader */
+#define GIET_OPEN_FILES_MAX      16         /* max simultaneously open files */
+#define GIET_NB_VSPACE_MAX	     64			/* max number of virtual spaces */
+#define GIET_TICK_VALUE	         100000 	/* context switch period (number of cycles) */
+#define GIET_USE_IOMMU           0          /* IOMMU activated when non zero */
+#define GIET_NO_HARD_CC          0          /* No hard cache coherence when non zero */
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/bdv_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/bdv_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/bdv_driver.c	(revision 283)
@@ -0,0 +1,329 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : ioc_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The ioc_driver.c and ioc_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib vci_block_device component, that is
+// a single channel, block oriented, external storage contrÃŽler.
+//
+// It can exist only one block-device controler in the architecture.
+//
+// The _bdv_read() and _bdv_write() functions use the _bdv_access() function,
+// that is always blocking, but can be called in 4 modes:
+//
+// - In BOOT_PA mode, the _bdv_access() function use the buffer virtual address 
+//   as a physical address (as the page tables are not build) and use a polling
+//   policy on the IOC_STATUS register to detect transfer completion, as
+//   hardware interrupts are not activated. This mode is used by the
+//   boot code to load the map.bin file into memory.
+//
+// - In BOOT_VA mode, the _bdv_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a polling policy on IOC_STATUS
+//   register to detect transfer completion. This mode is used by the boot code
+//   to load the various .elf files into memory.
+//
+// - In KERNEL mode, the _bdv_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a descheduling strategy:
+//   The ISR executed when transfer completes should restart the calling task. 
+//   There is no checking of user access right to the memory buffer.
+//   This mode must be used to access IOC, for an "open" system call.
+//
+// - In USER mode, the _bdv_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a descheduling strategy:
+//   The ISR executed when transfer completes should restart the calling task, 
+//   The user access right to the memory buffer must be checked.
+//   This mode must be used to access IOC, for a "read/write" system call.
+//
+// As the IOC component can be used by several programs running in parallel,
+// the _ioc_lock variable guaranties exclusive access to the device.  The
+// _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock.
+//
+// The IOMMU can be activated or not:
+// 
+// 1) When the IOMMU is used, a fixed size 2Mbytes vseg is allocated to 
+// the IOC peripheral, in the I/O virtual space, and the user buffer is
+// dynamically remapped in the IOMMU page table. The corresponding entry 
+// in the IOMMU PT1 is defined by the kernel _ioc_iommu_ix1 variable.
+// The number of pages to be unmapped is stored in the _ioc_npages variable.
+// The number of PT2 entries is dynamically computed and stored in the
+// kernel _ioc_iommu_npages variable. It cannot be larger than 512.
+// The user buffer is unmapped by the _ioc_completed() function when 
+// the transfer is completed.
+//
+// 2/ If the IOMMU is not used, we check that  the user buffer is mapped to a
+// contiguous physical buffer (this is generally true because the user space
+// page tables are statically constructed to use contiguous physical memory).
+//
+// Finally, the memory buffer must fulfill the following conditions:
+// - The buffer must be word aligned, 
+// - The buffer must be mapped in user space for an user access, 
+// - The buffer must be writable in case of (to_mem) access,
+// - The total number of physical pages occupied by the user buffer cannot
+//   be larger than 512 pages if the IOMMU is activated,
+// - All physical pages occupied by the user buffer must be contiguous
+//   if the IOMMU is not activated.
+// An error code is returned if these conditions are not verified.
+///////////////////////////////////////////////////////////////////////////////////
+// The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <ioc_driver.h>
+#include <bdv_driver.h>
+#include <utils.h>
+#include <tty_driver.h>
+#include <ctx_handler.h>
+
+///////////////////////////////////////////////////////////////////////////////
+//      _bdv_access()
+// This function transfer data between a memory buffer and the block device.
+// The buffer lentgth is (count*block_size) bytes.
+// Arguments are:
+// - to_mem     : from external storage to memory when non 0.
+// - kernel     : kernel buffer with identity mapping when non 0. 
+// - lba        : first block index on the external storage.
+// - buf_vaddr  : virtual base address of the memory buffer.
+// - count      : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+static unsigned int _bdv_access( unsigned int to_mem,
+                                 unsigned int mode,
+                                 unsigned int lba,
+                                 paddr_t buf_paddr,
+                                 unsigned int count) 
+{
+
+#if GIET_DEBUG_IOC_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[IOC DEBUG] Enter _bdv_access() at cycle ");
+_putd( _get_proctime() );
+_puts(" for processor ");
+_putd( _get_procid() );
+_puts("\n - mode    = ");
+_putd( mode );
+_puts("\n - paddr   = ");
+_putx( buf_paddr );
+_puts("\n - sectors = ");
+_putd( count );
+_puts("\n - lba     = ");
+_putx( lba );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ;
+    unsigned int error = 0;
+
+    // get the lock protecting IOC
+    _get_lock(&_ioc_lock);
+
+    // set the _ioc_status polling variable
+    _ioc_status = BLOCK_DEVICE_BUSY;
+
+    ioc_address[BLOCK_DEVICE_BUFFER]     = (unsigned int)buf_paddr;
+    ioc_address[BLOCK_DEVICE_BUFFER_EXT] = (unsigned int)(buf_paddr>>32);
+    ioc_address[BLOCK_DEVICE_COUNT]      = count;
+    ioc_address[BLOCK_DEVICE_LBA]        = lba;
+
+    // There is two policies for transfer completion 
+	// detection, depending on the mode argument:
+
+    if ( (mode == IOC_BOOT_PA_MODE) ||    // We poll directly the IOC_STATUS register
+         (mode == IOC_BOOT_VA_MODE) )     // as IRQs are masked.
+    {
+        // Launch transfert
+        if (to_mem == 0) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;
+        else             ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;
+
+        unsigned int status;
+        if ( _bdv_get_status(0, &status) ) return 1;
+
+        while( (status != BLOCK_DEVICE_READ_SUCCESS)  &&
+               (status != BLOCK_DEVICE_READ_ERROR)    &&
+               (status != BLOCK_DEVICE_WRITE_SUCCESS) &&
+               (status != BLOCK_DEVICE_WRITE_ERROR) ) 
+        {
+            if ( _bdv_get_status(0, &status) ) return 1;
+
+#if GIET_DEBUG_IOC_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[IOC DEBUG] _bdv_access() : ... waiting on IOC_STATUS register ...\n");
+_tty_release_lock( 0 );
+#endif
+
+        }
+        // analyse status
+        error = ( (status == BLOCK_DEVICE_READ_ERROR) ||
+                  (status == BLOCK_DEVICE_WRITE_ERROR) );
+
+        // release lock
+        _release_lock(&_ioc_lock);      
+    }
+    else                           // in USER or KERNEL mode, we deschedule the task.
+                                   // When the task is rescheduled by the ISR, we reset 
+                                   // the _ioc_status variable, and release the lock
+    {
+        // We need a critical section, because we must reset the RUN bit
+		// before to launch the transfer, and we want to avoid to be descheduled
+		// between these two operations. 
+
+        // Enter critical section
+        _it_disable(); 
+        
+        // set _ioc_gtid and reset runnable 
+        unsigned int ltid = _get_proc_task_id();
+        unsigned int pid = _get_procid();
+        _ioc_gtid = (pid<<16) + ltid;
+        _set_task_slot( pid, ltid, CTX_RUN_ID, 0 );  
+        
+        // Launch transfert
+        if (to_mem == 0) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE;
+        else             ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;
+
+        // deschedule task
+        _ctx_switch();                      
+
+        // analyse status
+        error = ( (_ioc_status == BLOCK_DEVICE_READ_ERROR) ||
+                  (_ioc_status == BLOCK_DEVICE_WRITE_ERROR) );
+
+        // reset _ioc_status and release lock
+        _ioc_status = BLOCK_DEVICE_IDLE; 
+        _release_lock(&_ioc_lock);      
+    }
+
+#if GIET_DEBUG_IOC_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[IOC DEBUG] _bdv_access completed at cycle ");
+_putd( _get_proctime() );
+_puts(" for processor ");
+_putd( _get_procid() );
+_puts(" : error = ");
+_putd( (unsigned int)error );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    return error;
+} // end _bdv_access()
+
+///////////////////////////////////////////////////////////////////////////////
+//       _bdv_init()
+// This function cheks block size, and activates the IOC interrupts.
+// Return 0 for success, > 0 if error
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _bdv_init( unsigned int channel )
+{
+    volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ;
+    
+    if ( ioc_address[BLOCK_DEVICE_BLOCK_SIZE] != 512 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n");
+        _tty_release_lock( 0 );
+        return 1; 
+    }
+
+    if ( channel != 0 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _bdv_init() : illegal channel\n");
+        _tty_release_lock( 0 );
+
+        return 1;
+    }
+
+    ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1;
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _bdv_read()
+// Transfer data from the block device to a memory buffer. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _bdv_read( unsigned int mode,  
+                        unsigned int lba, 
+                        paddr_t      buffer, 
+                        unsigned int count) 
+{
+    return _bdv_access( 1,        // read access
+                        mode,  
+                        lba,
+                        buffer,
+                        count );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _bdv_write()
+// Transfer data from a memory buffer to the block device. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _bdv_write( unsigned int mode,  
+                         unsigned int lba, 
+                         paddr_t  buffer, 
+                         unsigned int count ) 
+{
+    return _bdv_access( 0,        // write access
+                        mode,  
+                        lba,
+                        buffer,
+                        count );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _bdv_get_status()
+// This function returns in the status variable, the transfert status, and
+// acknowledge the IRQ if the IOC controler is not busy.
+// Returns 0 if success, > 0 if error
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _bdv_get_status( unsigned int  channel,
+                              unsigned int* status )
+{
+    if ( channel != 0 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _bdv_get_status() : illegal channel\n");
+        _tty_release_lock( 0 );
+
+        return 1;
+    }
+
+    // get IOC base address
+    volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
+    *status = ioc_address[BLOCK_DEVICE_STATUS];
+
+    return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _bdv_get_block_size()
+// This function returns the block_size with which the IOC has been configured.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _bdv_get_block_size() 
+{
+    // get IOC base address
+    volatile unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
+    
+    return  ioc_address[BLOCK_DEVICE_BLOCK_SIZE];
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/bdv_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/bdv_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/bdv_driver.h	(revision 283)
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File      : bdv_driver.h
+// Date      : 01/11/2013
+// Author    : alain greiner
+// Maintainer: cesar fuguet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_BDV_DRIVERS_H_
+#define _GIET_BDV_DRIVERS_H_
+
+#include <mapping_info.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+// BDV access functions and variables (vci_block_device)
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _bdv_init( unsigned int channel );
+
+extern unsigned int _bdv_write( unsigned int mode,
+                                unsigned int lba, 
+                                paddr_t      buffer, 
+                                unsigned int count );
+
+extern unsigned int _bdv_read(  unsigned int mode,
+                                unsigned int lba, 
+                                paddr_t      buffer,
+                                unsigned int count );
+
+extern unsigned int _bdv_get_status( unsigned int  channel,
+                                     unsigned int* status );
+
+extern unsigned int _bdv_get_block_size();
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/cma_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/cma_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/cma_driver.h	(revision 283)
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : cma_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_CMA_DRIVERS_H_
+#define _GIET_CMA_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// CMA (vci_chbuf_dma) registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum CMA_registers 
+{
+    CHBUF_RUN           = 0,    // write-only : channel activated
+    CHBUF_STATUS        = 1,    // read-only  : channel fsm state
+    CHBUF_SRC_DESC      = 2,    // read/write : source chbuf : descriptor base address
+    CHBUF_DST_DESC      = 3,    // read/write : destination chbuf : descriptor base address,
+    CHBUF_SRC_NBUFS     = 4,    // read/write : source chbuf : number of buffers,
+    CHBUF_DST_NBUFS     = 5,    // read/write : destination chbuf : number of buffers,
+    CHBUF_BUF_SIZE      = 6,    // read/write : buffer size for both source & destination  
+    CHBUF_PERIOD        = 7,    // read/write : period for status polling 
+    CHBUF_SRC_EXT       = 8,    // read/write : source chbuf : descriptor base address
+    CHBUF_DST_EXT       = 9,    // read/write : destination chbuf : descriptor base address,
+    /****/
+    CHBUF_CHANNEL_SPAN	= 1024,
+};
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/dma_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/dma_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/dma_driver.c	(revision 283)
@@ -0,0 +1,344 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : dma_driver.c
+// Date     : 23/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The dma_driver.c and dma_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the SoCLib vci_multi_dma component.
+// 
+// It can exist several DMA controlers in the architecture (one per cluster),
+// and each controller can contain several channels.
+// 
+// There is  (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:
+//        dma_id = cluster_xy * NB_DMA_CHANNELS + loc_id
+//
+// A DMA channel is a private ressource allocated to a given processor.
+// It is exclusively used by the kernet to speedup data transfers, and
+// there is no lock protecting exclusive access to the channel.
+// As the kernel uses a polling policy on the DMA_STATUS register to detect
+// transfer completion, the DMA IRQ is not used, and there is no DMA_ISR.
+////////////////////////////////////////////////////////////////////////////////////
+// The virtual base address of the segment associated to a channel is:
+//
+//    seg_dma_base + cluster_xy * vseg_cluster_increment + DMA_SPAN * channel_id
+//
+////////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <dma_driver.h>
+#include <utils.h>
+#include <tty_driver.h>
+#include <vmem.h>
+
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(NB_DMA_CHANNELS) 
+# error: You must define NB_DMA_CHANNELS in the hard_config.h file
+#endif
+
+extern unsigned int _ptabs_vaddr[];
+
+//////////////////////////////////////////////////////////////////////////////////
+// AS the GIET-VM uses a polling policy to detect transfer completion,
+// The DMA component initialisation must disable interrupts.
+// This function disables interrupts for one DMA channel in one cluster.
+// Returns 0 if success, returns > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _dma_init( unsigned int cluster_xy,
+                        unsigned int channel_id )
+{
+#if NB_DMA_CHANNELS > 0
+
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
+    if (channel_id >= NB_DMA_CHANNELS)  return 1; 
+
+    // compute DMA base address
+    unsigned int* dma_address = (unsigned int*) ((unsigned int)&seg_dma_base + 
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    // disable interrupt for selected channel
+    dma_address[channel_id * DMA_SPAN + DMA_IRQ_DISABLE] = 1;            
+    return 0;
+#else
+    return 1;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function re-initialises one DMA channel in one cluster after a transfer
+// completion. It actually forces the channel to return in iDLE state.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _dma_reset( unsigned int cluster_xy, 
+                         unsigned int channel_id ) 
+{
+#if NB_DMA_CHANNELS > 0
+
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
+    if (channel_id >= NB_DMA_CHANNELS)  return 1; 
+
+    // compute DMA base address
+    unsigned int* dma_address = (unsigned int*) ((unsigned int)&seg_dma_base + 
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    // reset selected channel
+    dma_address[channel_id * DMA_SPAN + DMA_RESET] = 0;            
+    return 0;
+#else
+    return 1;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function returns the status of a DMA channel in a given cluster
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _dma_get_status( unsigned int cluster_xy, 
+                              unsigned int channel_id ) 
+{
+#if NB_DMA_CHANNELS > 0
+
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
+    if (channel_id >= NB_DMA_CHANNELS)  return 1;
+
+    // compute DMA base address
+    unsigned int * dma_address = (unsigned int *) ((unsigned int)&seg_dma_base + 
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    // get selected channel status
+    return dma_address[channel_id * DMA_SPAN + DMA_LEN];
+#else
+    return DMA_IDLE;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function sets the physical address (including 64 bits extension)
+// for the source and destination buffers in a DMA channel in a given cluster
+// and sets the transfer size to lauch the transfer.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _dma_start_transfer( unsigned int       cluster_xy,
+                                  unsigned int       channel_id,
+                                  unsigned long long dst_paddr,   // physical address
+                                  unsigned long long src_paddr,   // physical address
+                                  unsigned int       size )       // bytes
+{
+#if NB_DMA_CHANNELS > 0
+
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
+    if (channel_id >= NB_DMA_CHANNELS)  return 1;
+
+    // compute DMA base address
+    unsigned int * dma_address = (unsigned int *) ((unsigned int)&seg_dma_base + 
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    // selected channel configuration and lauching
+    dma_address[channel_id * DMA_SPAN + DMA_SRC]     = (unsigned int)(src_paddr);
+    dma_address[channel_id * DMA_SPAN + DMA_SRC_EXT] = (unsigned int)(src_paddr>>32);
+    dma_address[channel_id * DMA_SPAN + DMA_DST]     = (unsigned int)(dst_paddr);
+    dma_address[channel_id * DMA_SPAN + DMA_DST_EXT] = (unsigned int)(dst_paddr>>32);
+    dma_address[channel_id * DMA_SPAN + DMA_LEN]     = (unsigned int)size;
+    return 0;
+#else
+    return 1;
+#endif
+}
+///////////////////////////////////////////////////////////////////////////////////
+// This function copies a source memory buffer to a destnation memory buffer, 
+// using the distributed DMA. As it makes virtual to physical address translation, 
+// the MMU should be activated. As there is one DMA channel per processor, 
+// the DMA cluster and channel indexes are obtained from the processor index.
+// The source and destination buffers base addresses must be word aligned, 
+// and the buffer's size must be multiple of 4.
+// In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 
+// message is displayed on TTY0, and the system crash.
+///////////////////////////////////////////////////////////////////////////////////
+// Note: this blocking function is supposed to be used by the kernel only, 
+// and uses a polling policy on DMA_STATUS register to detect completion.
+// Therefore, the DMA_IRQ is NOT used.
+///////////////////////////////////////////////////////////////////////////////////
+inline void  _dma_copy( unsigned int vspace_id, // vspace index for V2P
+                        void*        dest,      // dest buffer vbase
+                        const void*  source,    // source buffer vbase
+                        unsigned int size )     // bytes
+{
+#if NB_DMA_CHANNELS > 0
+
+    unsigned int procid    = _get_procid();
+    unsigned int cluster_xy = procid/NB_PROCS_MAX;
+    unsigned int channel_id = procid%NB_PROCS_MAX;
+
+    unsigned int ko;
+    unsigned int ppn;
+    unsigned int flags;
+
+#if GIET_DEBUG_DMA_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[DMA DEBUG] Enter _dma_copy() at cycle ");
+_putd( _get_proctime() );
+_puts("\n - vspace_id  = ");
+_putx( vspace_id );
+_puts("\n - cluster_xy = ");
+_putx( cluster_xy );
+_puts("\n - channel_id = ");
+_putx( channel_id );
+_puts("\n - dest       = ");
+_putx( (unsigned int)dest );
+_puts("\n - source     = ");
+_putx( (unsigned int)source );
+_puts("\n - bytes      = ");
+_putd( size );
+_tty_release_lock( 0 );
+#endif
+
+    // checking alignment constraints
+    if ( (((unsigned int)dest) & 0x3)   ||
+         (((unsigned int)source) & 0x3) ||
+         (size & 0x3) )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _dma_copy() : buffer unaligned\n");
+        _tty_release_lock( 0 );
+        _exit();
+    }
+
+    // get vspace 0 page table pointer 
+    unsigned int pt =  _ptabs_vaddr[vspace_id];
+
+    // get source buffer physical addresse
+    ko = _v2p_translate( (page_table_t*)pt,              // page table pointer
+                         ((unsigned int)source)>>12,     // vpn 
+                         &ppn,                           // ppn
+                         &flags );                       // flags
+    if ( ko ) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _dma_copy() : source buffer unmapped\n");
+        _tty_release_lock( 0 );
+        _exit();
+    }
+    unsigned long long src_paddr = (((unsigned long long)ppn) << 12) | 
+                                   ((unsigned int)source & 0x00000FFF);
+
+    // get dest buffer physical addresse
+    ko = _v2p_translate( (page_table_t*)pt,              // page table pointer
+                         ((unsigned int)dest)>>12,       // vpn 
+                         &ppn,                           // ppn
+                         &flags );                       // flags
+    if ( ko ) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _dma_copy() : dest buffer unmapped\n");
+        _tty_release_lock( 0 );
+        _exit();
+    }
+    unsigned long long dst_paddr = (((unsigned long long)ppn) << 12) | 
+                                   ((unsigned int)dest & 0x00000FFF);
+
+#if GIET_DEBUG_DMA_DRIVER
+_tty_get_lock( 0 );
+_puts("\n - src_paddr  = ");
+_putl( src_paddr );
+_puts("\n - dst_paddr  = ");
+_putl( dst_paddr );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // invalidate L1 cache if no hardware cache coherence
+    if ( GIET_NO_HARD_CC ) _dcache_buf_invalidate( dest, size );
+
+    // dma channel configuration & lauching
+    ko = _dma_start_transfer(  cluster_xy, channel_id, dst_paddr, src_paddr, size ); 
+    if ( ko ) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _dma_copy() : cannot start transfer\n");
+        _tty_release_lock( 0 );
+        _exit();
+    }
+
+    // scan dma channel status 
+    unsigned int status = _dma_get_status( cluster_xy, channel_id );
+    while( (status != DMA_SUCCESS) && 
+           (status != DMA_READ_ERROR) &&
+           (status != DMA_WRITE_ERROR) )
+    {
+        status = _dma_get_status( cluster_xy, channel_id );
+
+#if GIET_DEBUG_DMA_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register ...\n");
+_tty_release_lock( 0 );
+#endif
+
+    }
+    
+    // analyse status
+    if( status != DMA_SUCCESS )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _dma_copy() : DMA_STATUS error = ");
+        _putd( status );
+        _puts("\n");
+        _tty_release_lock( 0 );
+        _exit();
+    }
+    // reset dma channel
+    _dma_reset( cluster_xy, channel_id );
+
+#if GIET_DEBUG_DMA_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[DMA DEBUG] _dma_copy() completed at cycle ");
+_putd( _get_proctime() );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+#else // NB_DMA_CHANNELS == 0
+    _tty_get_lock( 0 );
+    _puts("\n[GIET ERROR] in _dma_copy() : NB_DMA_CHANNELS = 0 !\n");
+    _tty_release_lock( 0 );
+    _exit();
+#endif
+} // end _dma_copy
+
+
+
+
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/dma_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/dma_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/dma_driver.h	(revision 283)
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : dma_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_DMA_DRIVER_H_
+#define _GIET_DMA_DRIVER_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// Multi DMA registers offset
+///////////////////////////////////////////////////////////////////////////////////
+
+enum DMA_registers 
+{
+    DMA_SRC         = 0,
+    DMA_DST         = 1,
+    DMA_LEN         = 2,
+    DMA_RESET       = 3,
+    DMA_IRQ_DISABLE = 4,
+    DMA_SRC_EXT     = 5,
+    DMA_DST_EXT     = 6,
+    /**/
+    DMA_END         = 7,
+    DMA_SPAN        = 8,
+};
+
+enum SoclibDmaStatus 
+{
+    DMA_SUCCESS      = 0,
+    DMA_READ_ERROR   = 1,
+    DMA_IDLE         = 2,
+    DMA_WRITE_ERROR  = 3,
+    DMA_BUSY         = 4,
+};
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// Multi DMA variables and access functions  (vci_multi_dma)
+///////////////////////////////////////////////////////////////////////////////////
+
+// low level access functions
+extern unsigned int _dma_init( unsigned int cluster_xy,
+                               unsigned int channel_id );
+
+extern unsigned int _dma_reset( unsigned int  cluster_xy, 
+                                unsigned int  channel_id );
+
+extern unsigned int _dma_get_status( unsigned int  cluster_xy, 
+                                     unsigned int  channel_id );
+
+extern unsigned int _dma_start_transfer( unsigned int       cluster_xy,
+                                         unsigned int       channel_id,
+                                         unsigned long long dst_paddr,
+                                         unsigned long long src_paddr,
+                                         unsigned int       size );
+
+// higher level access function
+extern void _dma_copy(  unsigned int vspace_id,
+                        void*        dest,
+                        const void*  source,
+                        unsigned int size ); 
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/fbf_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/fbf_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/fbf_driver.c	(revision 283)
@@ -0,0 +1,453 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : fbf_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The fbf_driver.c and fbf_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the SoCLib vci_framebuffer component.
+//
+// It can exist only one frame buffer in the architecture.
+//
+// There exist two methods to access the VciFrameBuffer device:
+//  
+// 1) The _fb_sync_write() and _fb_sync_read() functions use a memcpy strategy 
+// to implement the transfer between a data buffer (user space) and the frame
+// buffer (kernel space). They are blocking until completion of the transfer.
+//
+// 2) The _fb_cma_init(), _fb_cma_write() and _fb_cma_stop() functions use
+// the VciChbufDma component (non replicated) to transfer a flow of images from
+// an user space chained buffer (two buffers) to the frame buffer.
+// A CMA channel must be allocated to the task requesting it in the mapping_info,
+// and stored in the task context.
+///////////////////////////////////////////////////////////////////////////////////
+// The seg_fbf_base virtual address must be defined in giet_vsegs.ld file.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <fbf_driver.h>
+#include <utils.h>
+#include <dma_driver.h>
+#include <cma_driver.h>
+#include <tty_driver.h>
+#include <ctx_handler.h>
+#include <mmc_driver.h>
+#include <vmem.h>
+
+#if !defined(GIET_USE_IOMMU) 
+# error: You must define GIET_USE_IOMMU in the giet_config.h file
+#endif
+
+#if !defined( USE_IOB )
+# error: You must define USE_IOB in the hard_config.h file
+#endif
+
+#define in_unckdata __attribute__((section (".unckdata")))
+
+////////////// memcpy approach //////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////
+// _fb_sync_write()
+// Transfer data from an memory buffer to the frame_buffer device using a memcpy. 
+// - offset : offset (in bytes) in the frame buffer.
+// - buffer : base address of the memory buffer.
+// - length : number of bytes to be transfered.
+//////////////////////////////////////////////////////////////////////////////////
+
+unsigned int _fb_sync_write(unsigned int offset, 
+                            const void * buffer, 
+                            unsigned int length) 
+{
+    char* fb_address = (char *)&seg_fbf_base + offset;
+    _memcpy( fb_address, buffer, length);
+    return 0;
+}
+//////////////////////////////////////////////////////////////////////////////////
+// _fb_sync_read()
+// Transfer data from the frame_buffer device to a memory buffer using a memcpy.
+// - offset : offset (in bytes) in the frame buffer.
+// - buffer : base address of the memory buffer.
+// - length : number of bytes to be transfered.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _fb_sync_read( unsigned int   offset, 
+                            void*          buffer, 
+                            unsigned int   length) 
+{
+    char* fb_address = (char *)&seg_fbf_base + offset;
+    _memcpy( buffer, fb_address, length);
+    return 0;
+}
+
+
+///////////////// CDMA approach //////////////////////////////////////////////////
+
+// This structure contains two chbuf descriptors that can be used by 
+// the VciChbufDma component to tranfer a flow of images:
+// - The SRC chbuf descriptor contain two slots (two user buffers)
+// - The DST chbuf descriptor contains only one slot (frame buffer)
+
+typedef struct fb_cma_channel_s
+{
+    paddr_t       buf0;     // physical address + status for user buffer 0 
+    paddr_t       buf1;     // physical address + status for user buffer 1
+    paddr_t       fbf;      // physical address + status for frame buffer
+    unsigned int  length;   // buffer length (number of bytes)
+    unsigned int  padding;  // unused (just to have channel size = 32 bytes)
+} fb_cma_channel_t;
+
+// array of FB_CMA channels descriptors (32 bytes per entry)
+// each entry contains one SRC and one DST chbuf descriptors.
+in_unckdata volatile fb_cma_channel_t 
+_fb_cma_channel[NB_CMA_CHANNELS] __attribute__((aligned(64)));
+
+// array of physical addresses for the FB_CMA channels descriptors
+in_unckdata volatile paddr_t          
+_fb_cma_desc_paddr[NB_CMA_CHANNELS];
+
+//////////////////////////////////////////////////////////////////////////////////////
+// _fb_cma_init()
+// This function uses the _fb_cma_channel[] and _fb_cma_desc_paddr[] arrays,
+// (that are both indexed by the channel index), and does four things:
+//
+// 1) computes the physical addresses for the two source user buffers, for 
+//    the destination frame buffer. It initialises the channel descriptor 
+//    _fb_cma_channel[i], containing the SRC chbuf descriptor (two buffers), 
+//    the DST chbuf descriptor (one single buffer), and the buffer length. 
+// 
+// 2) computes the physical address for the channel descriptor and register it
+//    in the _fb_cma_desc_paddr[i]. 
+//    
+// 3) makes a SYNC request to L2 cache for channel descriptor, because the
+//    channel descriptor is directly accessed in XRAM by the CMA component.
+//
+// 4) Starts the CMA hardware channel, that will poll the channel descriptor
+//    to fransfer an user buffer to the frame buffer as soon as the source 
+//    user buffer is marked valid.
+//
+// Returns 0 if success, > 0 if error 
+//////////////////////////////////////////////////////////////////////////////////////
+unsigned int _fb_cma_init( const void*  vbase0,  // first user buffer vbase address
+                           const void*  vbase1,  // second user buffer vbase address
+                           unsigned int length ) // buffer length (number of bytes)
+{
+#if NB_CMA_CHANNELS > 0
+
+    unsigned int  channel_id;          // CMA channel index
+    unsigned int  user_ptab;           // page table virtual address
+    unsigned int  ko;                  // unsuccessfull V2P translation
+    unsigned int  vaddr;               // virtual address
+    unsigned int  flags;               // protection flags
+    unsigned int  ppn;                 // physical page number
+    paddr_t       desc_paddr;          // physical address of channel descriptor
+
+    // get CMA channel index
+    channel_id = _get_context_slot(CTX_CMA_ID);
+    if ( channel_id >= NB_CMA_CHANNELS )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _fb_cma_init() : CMA channel index too large\n");
+        _tty_release_lock( 0 );
+        return 1;
+    }
+
+    // checking size for channel descriptor
+    if ( sizeof(fb_cma_channel_t) != 32 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel size\n");
+        _tty_release_lock( 0 );
+        return 1;
+    }
+
+    // checking channel descriptor alignment (32 bytes)
+    if ( (unsigned int)(&_fb_cma_channel[channel_id]) & 0x1F ) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel alignment\n");
+        _tty_release_lock( 0 );
+        return 1;
+    }
+
+    // checking user buffer virtual addresses and length alignment
+    if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer not word aligned\n");
+        _tty_release_lock( 0 );
+        return 1;
+    }
+
+    // get page table virtual address
+    user_ptab = _get_context_slot(CTX_PTAB_ID);
+
+    // compute and register frame buffer physical address
+    vaddr = ((unsigned int)&seg_fbf_base);
+    ko    = _v2p_translate( (page_table_t*) user_ptab, 
+                         (vaddr >> 12),
+                         &ppn, 
+                         &flags );
+    if (ko) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _fb_cma_init() : frame buffer unmapped\n");
+        _tty_release_lock( 0 );
+        return 1;
+    }
+    _fb_cma_channel[channel_id].fbf = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
+
+    // Compute and register first user buffer physical address
+    vaddr = (unsigned int)vbase0; 
+    ko = _v2p_translate( (page_table_t*) user_ptab, 
+                         (vaddr >> 12),
+                         &ppn, 
+                         &flags );
+    if (ko) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 0 unmapped\n");
+        _tty_release_lock( 0 );
+        return 1;
+    } 
+    if ((flags & PTE_U) == 0) 
+    {
+        _tty_get_lock( 0 );
+        _puts("[GIET ERROR] in _fb_cma_init() : user buffer 0 not in user space\n");
+        _tty_release_lock( 0 );
+        return 1; 
+    }
+    _fb_cma_channel[channel_id].buf0 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
+
+    // Compute and register second user buffer physical address
+    vaddr = (unsigned int)vbase1; 
+    ko = _v2p_translate( (page_table_t*) user_ptab, 
+                         (vaddr >> 12),
+                         &ppn, 
+                         &flags );
+    if (ko) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 1 unmapped\n");
+        _tty_release_lock( 0 );
+        return 1;
+    } 
+    if ((flags & PTE_U) == 0) 
+    {
+        _tty_get_lock( 0 );
+        _puts("[GIET ERROR] in _fb_cma_init() : user buffer 1 not in user space\n");
+        _tty_release_lock( 0 );
+        return 1; 
+    }
+    _fb_cma_channel[channel_id].buf1 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF);
+
+    // register buffer length in channel descriptor
+    _fb_cma_channel[channel_id].length = length;
+
+    // Compute and register physical adress of the channel descriptor
+    vaddr = (unsigned int)(&_fb_cma_channel[channel_id]);
+    ko = _v2p_translate( (page_table_t*) user_ptab, 
+                         (vaddr >> 12),
+                         &ppn, 
+                         &flags );
+    if (ko) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _fb_cma_init() : channel descriptor unmapped\n");
+        _tty_release_lock( 0 );
+        return 1;
+    } 
+    _fb_cma_desc_paddr[channel_id] = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
+
+    desc_paddr                     = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF);
+    
+
+#if GIET_DEBUG_FBF_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[CMA DEBUG] fb_cma_init()");
+_puts("\n - fbf       pbase = ");
+_putl( _fb_cma_channel[channel_id].fbf );
+_puts("\n - buf0      pbase = ");
+_putl( _fb_cma_channel[channel_id].buf0 );
+_puts("\n - buf1      pbase = ");
+_putl( _fb_cma_channel[channel_id].buf1 );
+_puts("\n - channel   pbase = ");
+_putl( _fb_cma_desc_paddr[channel_id] );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    if ( USE_IOB )
+    {
+        // SYNC request for channel descriptor
+        _memc_sync( desc_paddr, 32 );
+    }
+
+    // CMA channel activation
+    unsigned int* cma_vbase = (unsigned int *)&seg_cma_base;
+    unsigned int  offset    = channel_id * CHBUF_CHANNEL_SPAN;
+
+    cma_vbase[offset + CHBUF_SRC_DESC]  = (unsigned int)(desc_paddr & 0xFFFFFFFF);
+    cma_vbase[offset + CHBUF_SRC_EXT]   = (unsigned int)(desc_paddr >> 32);
+    cma_vbase[offset + CHBUF_SRC_NBUFS] = 2;
+    cma_vbase[offset + CHBUF_DST_DESC]  = (unsigned int)(desc_paddr & 0xFFFFFFFF) + 16;
+    cma_vbase[offset + CHBUF_DST_EXT]   = (unsigned int)(desc_paddr >> 32);
+    cma_vbase[offset + CHBUF_DST_NBUFS] = 1;
+    cma_vbase[offset + CHBUF_BUF_SIZE]  = length;
+    cma_vbase[offset + CHBUF_PERIOD]    = 300;
+    cma_vbase[offset + CHBUF_RUN]       = 1;
+
+    return 0;
+
+#else
+
+    _tty_get_lock( 0 );
+    _puts("\n[GIET ERROR] in _fb_cma_init() : no CMA channel allocated\n");
+    _tty_release_lock( 0 );
+
+    return 1;
+#endif
+}
+////////////////////////////////////////////////////////////////////////////////////
+// _fb_cma_write()
+//
+// It updates the status of the SRC and DST chbuf descriptors, to allow the CMA
+// component to transfer the source user buffer to the frame buffer.
+//
+// If the IO Bridge component is used:
+// 1) it makes an INVAL request for the channel descriptor, before testing the
+//    source buffer status, because it is modified in XRAM by the CMA component.
+// 2) it makes a SYNC request for the source user buffer before activating the CMA 
+//    transfer, because the data will be read from XRAM by the CMA component.
+// 3) it makes a SYNC request for the channel descriptor after modification 
+//    of the SRC and DST status, because these descriptors will be read from XRAM 
+//    by the CMA component.
+//
+// The buffer_id argument is the user buffer index (0 => buf0 / not 0 => buf1)
+// Returns 0 if success, > 0 if error 
+////////////////////////////////////////////////////////////////////////////////////
+unsigned int _fb_cma_write( unsigned int buffer_id )
+{
+#if NB_CMA_CHANNELS > 0
+
+    volatile paddr_t buf_paddr;
+    unsigned int     buf_length;
+    unsigned int     full = 1;
+
+    unsigned int     count = 0;
+
+    // get CMA channel index 
+    unsigned int channel_id = _get_context_slot(CTX_CMA_ID);
+
+#if GIET_DEBUG_FBF_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[CMA DEBUG] fb_cma_write() for CMA channel ");
+_putd( channel_id );
+_puts(" / buf_id = ");
+_putd( buffer_id );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // waiting buffer empty
+    while ( full )
+    {  
+        if ( USE_IOB )
+        {
+            // INVAL L2 cache for the channel descriptor,
+            _memc_inval( _fb_cma_desc_paddr[channel_id], 32 );
+
+            // INVAL L1 cache for the channel descriptor,
+            _dcache_buf_invalidate( &_fb_cma_channel[channel_id], 32 );
+        }
+
+        // read SRC buffer descriptor
+        if ( buffer_id == 0 ) buf_paddr = _fb_cma_channel[channel_id].buf0;
+        else                  buf_paddr = _fb_cma_channel[channel_id].buf1;
+        full = ( (unsigned int)(buf_paddr>>63) );
+
+        count++;
+        if ( count == 10 ) _exit();
+
+#if GIET_DEBUG_FBF_DRIVER
+_tty_get_lock( 0 );
+_puts(" - buffer descriptor = ");
+_putl( buf_paddr );
+_puts(" at cycle ");
+_putd( _get_proctime() );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    }
+
+    if ( USE_IOB )
+    {
+        // SYNC request for the user buffer because 
+        // this buffer will be read from XRAM by the CMA component
+        _memc_sync( buf_paddr, _fb_cma_channel[channel_id].length );
+    }
+
+    // set SRC full 
+    if ( buffer_id == 0 )
+    _fb_cma_channel[channel_id].buf0 = buf_paddr | 0x8000000000000000ULL;
+    else
+    _fb_cma_channel[channel_id].buf1 = buf_paddr | 0x8000000000000000ULL;
+
+    // set DST empty
+    _fb_cma_channel[channel_id].fbf  = _fb_cma_channel[channel_id].fbf
+                                       & 0x7FFFFFFFFFFFFFFFULL;
+
+    if ( USE_IOB )
+    {
+        // SYNC request for the channel descriptor, because
+        // it will be read in XRAM by the CMA component
+        _memc_sync( _fb_cma_desc_paddr[channel_id], 32 );
+    }
+
+    return 0;
+
+#else
+
+    _tty_get_lock( 0 );
+    _puts("\n[GIET ERROR] in _fb_cma_channel() : no CMA channel allocated\n");
+    _tty_release_lock( 0 );
+    return 1;
+
+#endif
+}
+//////////////////////////////////////////////////////////////////////////////////
+// _fb_cma_stop()
+// This function desactivates the CMA channel allocated to the calling task.
+// Returns 0 if success, > 0 if error 
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _fb_cma_stop( unsigned int buffer_id )
+{
+#if NB_CMA_CHANNELS > 0
+
+    // get CMA channel allocated 
+    unsigned int channel_id = _get_context_slot(CTX_CMA_ID);
+
+    // CMA channel desactivation
+    unsigned int* cma_vbase = (unsigned int *)&seg_cma_base;
+    unsigned int  offset     = channel_id * CHBUF_CHANNEL_SPAN;
+    cma_vbase[offset + CHBUF_RUN] = 0;
+    return 0;
+
+#else
+
+    _tty_get_lock( 0 );
+    _puts("\n[GIET ERROR] in _fb_cma_stop() : no CMA channel allocated\n");
+    _tty_release_lock( 0 );
+    return 1;
+
+#endif
+}
+    
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/fbf_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/fbf_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/fbf_driver.h	(revision 283)
@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : fbf_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_FBF_DRIVERS_H_
+#define _GIET_FBF_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// Frame Buffer access functions  (vci_frame_buffer)
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _fb_sync_write( unsigned int offset, 
+                                    const void * buffer, 
+                                    unsigned int length );
+
+extern unsigned int _fb_sync_read(  unsigned int offset, 
+                                    void *       buffer, 
+                                    unsigned int length );
+
+extern unsigned int _fb_cma_init( const void*  vbase0,
+                                  const void*  vbase1,
+                                  unsigned int length );
+
+extern unsigned int _fb_cma_write( unsigned int buffer_id );
+
+extern unsigned int _fb_cma_stop();
+
+///////////////////////////////////////////////////////////////////////////////////
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/hba_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/hba_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/hba_driver.c	(revision 283)
@@ -0,0 +1,510 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : hba_driver.c
+// Date     : 23/11/2013
+// Author   : alain greiner and zhang
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The hba_driver.c and hba_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib VciMultiAhci component, that is a multi-channels,
+// block oriented, external storage contrÃŽler, respecting the AHCI standard.
+//
+// It can exist only one ahci-device controler in the architecture.
+//
+// The _ioc_read() and _ioc_write() functions use the _ioc_access() function,
+// that is always blocking, but can be called in 4 modes:
+//
+// - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address 
+//   as a physical address (as the page tables are not build) and use a polling
+//   policy on the IOC_STATUS register to detect transfer completion, as
+//   hardware interrupts are not activated. This mode is used by the
+//   boot code to load the map.bin file into memory.
+//
+// - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a polling policy on IOC_STATUS
+//   register to detect transfer completion. This mode is used by the boot code
+//   to load the various .elf files into memory.
+//
+// - In KERNEL mode, the _ioc_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a descheduling strategy:
+//   The ISR executed when transfer completes should restart the calling task. 
+//   There is no checking of user access right to the memory buffer.
+//   This mode must be used to access IOC, for an "open" system call.
+//
+// - In USER mode, the _ioc_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a descheduling strategy:
+//   The ISR executed when transfer completes should restart the calling task, 
+//   The user access right to the memory buffer must be checked.
+//   This mode must be used to access IOC, for a "read/write" system call.
+//
+// As the IOC component can be used by several programs running in parallel,
+// the _ioc_lock variable guaranties exclusive access to the device.  The
+// _ioc_read() and _ioc_write() functions use atomic LL/SC to get the lock.
+//
+// The IOMMU can be activated or not:
+// 
+// 1) When the IOMMU is used, a fixed size 2Mbytes vseg is allocated to 
+// the IOC peripheral, in the I/O virtual space, and the user buffer is
+// dynamically remapped in the IOMMU page table. The corresponding entry 
+// in the IOMMU PT1 is defined by the kernel _ioc_iommu_ix1 variable.
+// The number of pages to be unmapped is stored in the _ioc_npages variable.
+// The number of PT2 entries is dynamically computed and stored in the
+// kernel _ioc_iommu_npages variable. It cannot be larger than 512.
+// The user buffer is unmapped by the _ioc_completed() function when 
+// the transfer is completed.
+//
+// 2/ If the IOMMU is not used, we check that  the user buffer is mapped to a
+// contiguous physical buffer (this is generally true because the user space
+// page tables are statically constructed to use contiguous physical memory).
+//
+// Finally, the memory buffer must fulfill the following conditions:
+// - The buffer must be word aligned, 
+// - The buffer must be mapped in user space for an user access, 
+// - The buffer must be writable in case of (to_mem) access,
+// - The total number of physical pages occupied by the user buffer cannot
+//   be larger than 512 pages if the IOMMU is activated,
+// - All physical pages occupied by the user buffer must be contiguous
+//   if the IOMMU is not activated.
+// An error code is returned if these conditions are not verified.
+///////////////////////////////////////////////////////////////////////////////////
+// The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <ioc_driver.h>
+#include <utils.h>
+#include <tty_driver.h>
+#include <iob_driver.h>
+#include <ctx_handler.h>
+#include <mmc_driver.h>
+#include <vmem.h>
+
+#if !defined( NB_HBA_CHANNELS )
+# error: You must define NB_HBA_CHANNELS in the hard_config.h file
+#endif
+
+#if ( NB_HBA_CHANNELS > 8 )
+# error: NB_HBA_CHANNELS cannot be larger than 8
+#endif
+
+#if !defined( USE_IOB )
+# error: You must define USE_IOB in the hard_config.h file
+#endif
+
+#if !defined(GIET_USE_IOMMU) 
+# error: You must define GIET_USE_IOMMU in the giet_config.h file
+#endif
+
+#define in_unckdata __attribute__((section (".unckdata")))
+
+//////////////////////////////////////////////////////////////////
+//  Global variables
+//////////////////////////////////////////////////////////////////
+
+// command list array (one per channel)
+hba_cmd_list_t   hba_cmd_list[NB_HBA_CHANNELS] __attribute__((aligned(0x1000)));   
+
+// command tables array (32 command tables per channel)
+hba_cmd_table_t  hba_cmd_table[NB_HBA_CHANNELS][32] __attribute__((aligned(0x1000))); 
+
+// command list physical addresses array (one per channel)
+paddr_t          hba_cmd_list_paddr[NB_HBA_CHANNELS];
+
+// command tables physical addresses array (32 command tables per channel)
+paddr_t          hba_cmd_table_paddr[NB_HBA_CHANNELS][32];
+
+// command list pointer array (one per channel)
+unsigned int     hba_cmd_slot[NB_HBA_CHANNELS];
+
+//////////////////////////////////////////////////////////////////
+// This function returns the status of a given channel.
+// return 0 if success, >0 if error
+//////////////////////////////////////////////////////////////////
+unsigned int _hba_get_status( unsigned int   channel, 
+                              unsigned int*  status )
+{
+    volatile unsigned int* hba_address;
+    hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN*channel);
+
+    if( channel >= NB_HBA_CHANNELS )
+    {
+        _get_lock(&_tty_put_lock);
+        _puts("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");
+        _release_lock(&_tty_put_lock);
+        return 1;
+    }
+    else
+    {
+        *status = hba_address[HBA_PXIS];
+        return 0;
+    }
+}
+//////////////////////////////////////////////////////////////////
+// This function reset the status resgister for a given channel.
+// return 0 if success, >0 if error
+//////////////////////////////////////////////////////////////////
+unsigned int _hba_reset_status( unsigned int channel )
+{
+    volatile unsigned int* hba_address;
+    hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN*channel);
+
+    if( channel >= NB_HBA_CHANNELS )
+    {   
+        _get_lock(&_tty_put_lock);
+        _puts("\n[GIET ERROR] in _hba_reset_status() : illegal channel\n");
+        _release_lock(&_tty_put_lock);
+        return 1;
+    }
+    else
+    {
+        hba_address[HBA_PXIS] = 0;
+        return 0;
+    }
+}
+///////////////////////////////////////////////////////////////////////////////
+// This function register a command in both the command list
+// and the command table, and updates the HBA_PXCI register.
+// It uses the AHCI Scatter/Gather mechanisme to split the user 
+// buffer in several physical buffers, with the constraint that each physical
+// buffer must be an integer number of blocks entirely contained in a single
+// page frame. 
+// return 0 if success, > 0 if error
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _hba_cmd_set( unsigned int  is_read,     // to memory
+                           unsigned int  lba,         // logic block address
+                           unsigned int  buf_vaddr,   // buffer virtual address
+                           unsigned int  count )      // number of blocks
+{
+    volatile unsigned int *hba_address;
+
+    unsigned int       block_size;     // defined by the block device (bytes)
+    unsigned int       channel_id;     // channel index
+    unsigned int       pxci;           // command list status
+    unsigned int       cmd_id;         // command index in command list
+    unsigned int       buf_id;         // for physical buffers covering user buffer
+    unsigned int       user_pt_vbase;  // user page table virtual base address
+    unsigned int       vpn;            // for all pages covering the userbuffer
+    unsigned int       vpn_min;        // first virtual page index for user buffer
+    unsigned int       vpn_max;        // last  virtual page index for user buffer
+    unsigned int       offset;         // unaligned bytes in page frame: buf_vaddr & 0xFFF 
+    unsigned int       offset_last;    // unaligned bytes in last frame
+    hba_cmd_desc_t*    cmd_desc;       // command descriptor pointer   
+    hba_cmd_table_t*   cmd_table;      // command table pointer
+
+    // TODO The block size must be obtained from the hardware...
+    block_size = 512;
+
+    // check buffer alignment
+    if( buf_vaddr & (block_size-1) )
+    {
+        _get_lock(&_tty_put_lock);
+        _puts("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");
+        _release_lock(&_tty_put_lock);
+        return 1;
+    }
+
+    // get channel index
+    channel_id = _get_context_slot(CTX_HBA_ID);
+    if ( channel_id == 0xFFFFFFFF )
+    {
+        _get_lock(&_tty_put_lock);
+        _puts("\n[GIET ERROR] in _hba_set_cmd() : no HBA channel allocated\n");
+        _release_lock(&_tty_put_lock);
+        return 1;
+    }
+
+    // get hba device address
+    hba_address = (unsigned int*)(&seg_ioc_base) + (HBA_SPAN * channel_id);
+
+    // get command list status
+    pxci = hba_address[HBA_PXCI];
+
+    // get command index and return error if command list full
+    cmd_id = hba_cmd_slot[channel_id];
+    if( pxci & (1<<cmd_id ) ) 
+    {
+        _get_lock(&_tty_put_lock);
+        _puts("\n[GIET ERROR] in _hba_set_cmd() : command list full in channel \n");
+        _putd( channel_id );
+        _puts("\n");
+        _release_lock(&_tty_put_lock);
+        return 1;
+    }
+
+    // compute pointers on command descriptor and command table    
+    cmd_desc  = (hba_cmd_desc_t*)(&(hba_cmd_list[channel_id].desc[cmd_id]));
+    cmd_table = (hba_cmd_table_t*)(&(hba_cmd_table[channel_id][cmd_id]));
+
+    // get user space page table virtual address
+    user_pt_vbase     = _get_context_slot(CTX_PTAB_ID);
+    vpn_min           = buf_vaddr >> 12;
+    vpn_max           = (buf_vaddr + (block_size*count) - 1) >> 12;
+    offset            = buf_vaddr & 0xFFF;
+    offset_last       = (buf_vaddr + (block_size*count) - 1) & 0xFFF;
+
+    // initialize all buffer descriptors in command table 
+    // (loop on all virtual pages covering the user buffer)
+    for( vpn = vpn_min, buf_id = 0 ; vpn <= vpn_max ; vpn++ )
+    {
+        paddr_t      paddr;
+        unsigned int count;
+        unsigned int ppn;
+        unsigned int flags;
+        unsigned int ko;
+        unsigned int buf_id = 0;
+
+        // get ppn and flags 
+        ko = _v2p_translate( (page_table_t*)user_pt_vbase,
+                              vpn,
+                              &ppn,
+                              &flags );
+
+        // check access rights
+        if ( ko )
+        {
+            _get_lock(&_tty_put_lock);
+            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n");
+            _release_lock(&_tty_put_lock);
+            return 1;
+        }
+        if ((flags & PTE_U) == 0)
+        {
+            _get_lock(&_tty_put_lock);
+            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");
+            _release_lock(&_tty_put_lock);
+            return 1;
+        }
+        if (((flags & PTE_W) == 0 ) && (is_read == 0) )
+        {
+            _get_lock(&_tty_put_lock);
+            _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");
+            _release_lock(&_tty_put_lock);
+            return 1;
+        }
+
+        // check buffer index overflow
+        if( buf_id > 245 )
+        {
+            _get_lock(&_tty_put_lock);
+            _puts("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");
+            _release_lock(&_tty_put_lock);
+            return 1;
+        }
+
+        // buffer allocation
+        if( vpn == vpn_min )       // first page: one single buffer
+        {
+            paddr = (((paddr_t)ppn) << 12) + offset;
+            count = 0x1000 - offset;
+            cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
+            cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
+            cmd_table->entry[buf_id].dbc  = count;
+
+#if GIET_DEBUG_HBA_DRIVER
+_puts("\n- buf_index = ");
+_putd( buf_id );
+_puts(" / paddr = ");
+_putl( paddr );
+_puts(" / count = ");
+_putd( count );
+_puts("\n");
+#endif
+            buf_id++;
+        }
+        else if( vpn == vpn_max )  // last page: one single buffer
+        {
+            paddr = (((paddr_t)ppn) << 12);
+            count = offset_last;
+            cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
+            cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
+            cmd_table->entry[buf_id].dbc  = count;
+
+#if GIET_DEBUG_HBA_DRIVER
+_puts("\n- buf_index = ");
+_putd( buf_id );
+_puts(" / paddr = ");
+_putl( paddr );
+_puts(" / count = ");
+_putd( count );
+_puts("\n");
+#endif
+            buf_id++;
+        }
+        else if( offset )          // midle page and offset != 0: two buffers  
+        {
+            paddr = (((paddr_t)ppn) << 12);
+            
+            count = offset;
+            cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
+            cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
+            cmd_table->entry[buf_id].dbc  = count;
+
+#if GIET_DEBUG_HBA_DRIVER
+_puts("\n- buf_index = ");
+_putd( buf_id );
+_puts(" / paddr = ");
+_putl( paddr );
+_puts(" / count = ");
+_putd( count );
+_puts("\n");
+#endif
+            buf_id++;
+
+            paddr = (((paddr_t)ppn) << 12) + offset;
+            count = 0x1000 - offset; 
+            cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
+            cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
+            cmd_table->entry[buf_id].dbc  = count;
+
+#if GIET_DEBUG_HBA_DRIVER
+_puts("\n- buf_index = ");
+_putd( buf_id );
+_puts(" / paddr = ");
+_putl( paddr );
+_puts(" / count = ");
+_putd( count );
+_puts("\n");
+#endif
+            buf_id++;
+        }
+        else                      // middle page and offset == 0: one buffer
+        {
+            paddr = (((paddr_t)ppn) << 12);
+            count = 0x1000; 
+            cmd_table->entry[buf_id].dba  = (unsigned int)(paddr);
+            cmd_table->entry[buf_id].dbau = (unsigned int)(paddr >> 32);
+            cmd_table->entry[buf_id].dbc  = count;
+
+#if GIET_DEBUG_HBA_DRIVER
+_puts("\n- buf_index = ");
+_putd( buf_id );
+_puts(" / paddr = ");
+_putl( paddr );
+_puts(" / count = ");
+_putd( count );
+_puts("\n");
+#endif
+            buf_id++;
+        }
+    }
+
+    // initialize command table header
+    cmd_table->header.lba0 = (char)lba;
+    cmd_table->header.lba1 = (char)(lba>>8);
+    cmd_table->header.lba2 = (char)(lba>>16);
+    cmd_table->header.lba3 = (char)(lba>>24);
+
+    // initialise command descriptor
+    cmd_desc->prdtl[0] = (unsigned char)(buf_id);
+    cmd_desc->prdtl[1] = (unsigned char)(buf_id>>8);
+    cmd_desc->ctba     = (unsigned int)(hba_cmd_table_paddr[channel_id][cmd_id]);
+    cmd_desc->ctbau    = (unsigned int)(hba_cmd_table_paddr[channel_id][cmd_id]>>32);
+    if( is_read ) cmd_desc->flag[0] = 0x00;
+    else          cmd_desc->flag[0] = 0x40;     
+   
+    // update PXCI register
+    hba_address[HBA_PXCI] = (1<<cmd_id);
+
+    // update command pointer 
+    hba_cmd_slot[channel_id] = (cmd_id + 1)%32;
+
+    return  0;
+} 
+///////////////////////////////////////////////////////////////////
+// Register a write command in Command List and Command Table
+// for a single buffer.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////
+unsigned int _hba_write( unsigned int  lba,
+                         void*         buffer, 
+                         unsigned int  count )
+{
+    return _hba_cmd_set( 0, lba, (unsigned int)buffer, count );
+}
+
+///////////////////////////////////////////////////////////////////
+// Register a read command in Command List and Command Table
+// for a single buffer.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////
+unsigned int _hba_read( unsigned int  lba, 
+                        void*         buffer, 
+                        unsigned int  count )
+{
+    return _hba_cmd_set( 1, lba, (unsigned int)buffer, count );
+}
+//////////////////////////////////////////////////////////////////
+// This function initializes for a given channel
+// - the HBA hardware registers,
+// - the command list pointer,
+// - the command lists physical addresse,
+// - the command tables physical addresses array,
+//////////////////////////////////////////////////////////////////
+void _hba_init( unsigned int channel )
+{
+    unsigned int ppn;
+    unsigned int flags;
+    unsigned int fail;
+    unsigned int vbase;
+    unsigned int c;               // c == command index
+
+    // get page_table pointer
+    unsigned int pt = _get_context_slot(CTX_PTAB_ID);
+
+    // HBA registers
+    unsigned int*  hba_address;
+    hba_address = (unsigned int*)&seg_ioc_base + HBA_SPAN * channel;
+
+    hba_address[HBA_PXCLB]  = (unsigned int)(&hba_cmd_list[channel]);
+    hba_address[HBA_PXCLBU] = 0;
+    hba_address[HBA_PXIE]   = 0x40000001;
+    hba_address[HBA_PXIS]   = 0;
+    hba_address[HBA_PXCI]   = 0;
+    hba_address[HBA_PXCMD]  = 1;
+
+    // command list pointer       
+    hba_cmd_slot[channel] = 0;
+
+    // Command list physical addresse
+    vbase = (unsigned int)(&hba_cmd_list[channel]);
+    fail = _v2p_translate( (page_table_t*)pt,
+                           vbase>>12,
+                           &ppn,
+                           &flags );
+    if ( fail )
+    {
+        _get_lock(&_tty_put_lock);
+        _puts("[GIET ERROR] in _hba_init() : command list unmapped\n");
+        _release_lock(&_tty_put_lock);
+        _exit();
+    }
+    hba_cmd_list_paddr[channel] = ((paddr_t)ppn) | (vbase & 0xFFF);
+
+    // Command tables physical addresses
+    for( c=0 ; c<32 ; c++ )
+    {
+        vbase = (unsigned int)(&hba_cmd_table[channel][c]);
+        fail = _v2p_translate( (page_table_t*)pt,
+                               vbase>>12,
+                               &ppn,
+                               &flags );
+        if ( fail )
+        {
+            _get_lock(&_tty_put_lock);
+            _puts("[GIET ERROR] in _hba_init() : command table unmapped\n");
+            _release_lock(&_tty_put_lock);
+            _exit();
+        }
+        hba_cmd_table_paddr[channel][c] = ((paddr_t)ppn) | (vbase & 0xFFF);
+    }
+}
+
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/hba_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/hba_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/hba_driver.h	(revision 283)
@@ -0,0 +1,124 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : hba_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner and zhang
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_HBA_DRIVERS_H_
+#define _GIET_HBA_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// HBA component registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum SoclibMultiAhciRegisters 
+{
+  HBA_PXCLB            = 0,         // command list base address 32 LSB bits
+  HBA_PXCLBU           = 1,         // command list base address 32 MSB bits
+  HBA_PXIS             = 4,         // interrupt status
+  HBA_PXIE             = 5,         // interrupt enable
+  HBA_PXCMD            = 6,         // run
+  HBA_PXCI             = 14,        // command bit-vector     
+  HBA_SPAN             = 0x400,     // 4 Kbytes per channel => 1024 slots
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// Data structures for command table array
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct hba_cmd_header_s // size = 128 bytes
+{
+    // WORD 0
+    unsigned int        res0;       // reserved	
+  
+    // WORD 1
+    unsigned char	    lba0;	    // LBA 7:0
+    unsigned char	    lba1;	    // LBA 15:8
+    unsigned char	    lba2;	    // LBA 23:16
+    unsigned char	    res1;	    // reserved
+  
+    // WORD 2
+    unsigned char	    lba3;	    // LBA 31:24
+    unsigned char	    lba4;	    // LBA 39:32
+    unsigned char	    lba5;	    // LBA 47:40
+    unsigned char	    res2;	    // reserved
+  
+    // WORD 3 to 31
+    unsigned int        res[29];    // reserved	
+
+} hba_cmd_header_t;
+
+typedef struct hba_cmd_entry_s  // size = 16 bytes
+{
+    unsigned int        dba;	    // Buffer base address 32 LSB bits
+    unsigned int        dbau;	    // Buffer base address 32 MSB bits
+    unsigned int        res0;	    // reserved
+    unsigned int        dbc;	    // Buffer byte count
+
+} hba_cmd_entry_t;
+
+typedef struct hba_cmd_table_s  // size = 256 bytes
+{
+
+    hba_cmd_header_t   header;     // contains LBA
+    hba_cmd_entry_t    entry[248]; // 248 buffers max
+
+} hba_cmd_table_t;
+
+///////////////////////////////////////////////////////////////////////////////////
+// Data structures for command list array
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct hba_cmd_desc_s  // size = 16 bytes
+{
+	// WORD 0
+    unsigned char       flag[2];    // W in bit 6 of flag[0]
+    unsigned char       prdtl[2];	// Number of buffers
+
+    // WORD 1
+    unsigned int        prdbc;		// Number of bytes actually transfered
+
+    // WORD 2, WORD 3
+    unsigned int        ctba;		// Command Table base address 32 LSB bits
+    unsigned int        ctbau;		// Command Table base address 32 MSB bits
+
+} hba_cmd_desc_t;
+
+typedef struct hba_cmd_list_s  // size = 512 bytes
+{
+    // 32 command descriptors
+    hba_cmd_desc_t desc[32];
+
+} hba_cmd_list_t;
+
+///////////////////////////////////////////////////////////////////////////////////
+// HBA device access functions  (vci_multi_nic)
+///////////////////////////////////////////////////////////////////////////////////
+
+unsigned int _hba_write( unsigned int lba,       // logic bloc address on device
+                         void*        buffer,    // memory buffer base address
+                         unsigned int count );   // number of blocs
+
+unsigned int _hba_read ( unsigned int lba,       // logic bloc address on device
+                         void*        buffer,    // memory buffer base address
+                         unsigned int count );   // number of blocks
+
+void _hba_init(); 
+
+unsigned int _hba_get_status( unsigned int   channel,
+                              unsigned int*  status );
+
+unsigned int _hba_reset_status( unsigned int channel );
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/icu_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/icu_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/icu_driver.c	(revision 283)
@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : icu_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The icu_driver.c and icu_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the SoCLib vci_icu component, That is a vectorised
+// interrupt controler.
+//
+// It can exist several interrupt controller unit in the architecture 
+// (one per cluster), and each one can contain several channels.
+// The number of ICU channels is equal to NB_PROCS_MAX, because there is 
+// one private ICU channel per processor in a cluster.
+////////////////////////////////////////////////////////////////////////////////
+// The virtual base address of the segment associated to the component is:
+//
+//      seg_icu_base + cluster_xy * vseg_cluster_increment 
+//
+// The seg_icu_base and vseg_cluster_increment values must be defined 
+// in giet_vsegs.ld file.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <icu_driver.h>
+#include <tty_driver.h>
+#include <utils.h>
+
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(NB_PROCS_MAX) 
+# error: You must define NB_PROCS_MAX in the hard_config.h file
+#endif
+
+#if !defined( USE_XICU )
+# error: You must define USE_XICU in the hard_config.h file
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+//     _icu_set_mask()
+// This function set the mask register for the ICU channel identified 
+// by the cluster index and the processor index.
+// All '1' bits are set / all '0' bits are not modified.
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _icu_set_mask( unsigned int cluster_xy,
+                            unsigned int proc_id,
+                            unsigned int value )
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1; 
+
+#if USE_XICU
+    _puts("[GIET ERROR] _icu_set_mask() should not be used if USE_XICU is set\n");
+    return 1;
+#else
+    unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_icu_base + 
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+    icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 
+    return 0;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//     _icu_get_index()
+// This function returns the index of the highest priority (smaller index) IRQ.
+// The ICU channel is identified by the cluster index and the processor index.
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _icu_get_index( unsigned int cluster_xy, 
+                             unsigned int proc_id, 
+                             unsigned int * buffer) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+    if (proc_id >= NB_PROCS_MAX) return 1;
+
+#if USE_XICU
+    _puts("[GIET ERROR] _icu_get_index() should not be used if USE_XICU is set\n");
+    return 1;
+#else
+    unsigned int* icu_address = (unsigned int *) ((unsigned int)&seg_icu_base + 
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+    *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 
+    return 0;
+#endif
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/icu_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/icu_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/icu_driver.h	(revision 283)
@@ -0,0 +1,50 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : icu_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_ICU_DRIVER_H_
+#define _GIET_ICU_DRIVER_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// ICU registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum ICU_registers 
+{
+    ICU_INT         = 0,
+    ICU_MASK        = 1,
+    ICU_MASK_SET    = 2,
+    ICU_MASK_CLEAR  = 3,
+    ICU_IT_VECTOR   = 4,
+    /**/
+    ICU_END         = 5,
+    ICU_SPAN        = 8,
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// ICU and XICU access functions 
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _icu_get_index( unsigned int cluster_xy, 
+                                    unsigned int proc_id, 
+                                    unsigned int * buffer );
+
+extern unsigned int _icu_set_mask( unsigned int cluster_xy,
+                                   unsigned int proc_id,
+                                   unsigned int value );
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/iob_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/iob_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/iob_driver.c	(revision 283)
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : iob_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The iob_driver.c and iob_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the TSAR vci_io_bridge, that is a bridge to access
+// The external peripherals, implementing an IO_MMU.
+///////////////////////////////////////////////////////////////////////////////////
+// The seg_iob_base virtual base addresses must be defined in giet_vsegs.ld file.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <iob_driver.h>
+#include <utils.h>
+
+#if !defined(GIET_USE_IOMMU) 
+# error: You must define GIET_USE_IOMMU in the giet_config.h file
+#endif
+
+#if !defined( USE_IOB )
+# error: You must define USE_IOB in the hard_config.h file
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//      _iob_inval_tlb_entry()
+// This function invalidates a TLB entry identified by a virtual address.
+// Returns 0 if success, returns 1 if failure
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _iob_inval_tlb_entry( unsigned int vaddr )
+{
+#if USE_IOB
+
+    unsigned int * iob_address = (unsigned int *) &seg_iob_base ;
+    iob_address[IOB_INVAL_PTE] = vaddr;
+    return 0; 
+
+#else
+
+    return 1;
+
+#endif
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/iob_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/iob_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/iob_driver.h	(revision 283)
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : iob_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_IOB_DRIVER_H_
+#define _GIET_IOB_DRIVER_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// TSAR IOB (vci_io_bridge) registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum IOB_registers 
+{
+    IOB_IOMMU_PTPR       = 0, /* R/W : Page Table Pointer Register */
+    IOB_IOMMU_ACTIVE     = 1, /* R/W : IOMMU activated if not 0 */
+    IOB_IOMMU_BVAR       = 2, /* R   : Bad Virtual Address (unmapped) */
+    IOB_IOMMU_ETR        = 3, /* R   : Error Type */
+    IOB_IOMMU_BAD_ID     = 4, /* R   : Faulty Peripheral Index */
+    IOB_INVAL_PTE        = 5, /* W   : Invalidate a PTE (virtual address) */
+    IOB_IT_ADDR_IOMMU_LO = 6, /* W/R : 32 LSB bits for IOMMU IT*/
+    IOB_IT_ADDR_IOMMU_HI = 7, /* W/R : 32 MSB bits for IOMMU IT */
+    IOB_IT_ADDRESS_BEGIN = 8, /* R/W : Peripheral IT address (2 32 bits registers) */
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// TSAR IOB access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _iob_inval_tlb_entry( unsigned int vaddr );
+
+extern unsigned int _iob_set_iommu_ptpr( unsigned int value );
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.c	(revision 283)
@@ -0,0 +1,401 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : ioc_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The ioc_driver.c and ioc_driver.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib vci_block_device component, that is
+// a single channel, block oriented, external storage contrÃŽler.
+//
+// It can exist only one block-device controler in the architecture.
+//
+// The _ioc_read() and _ioc_write() functions use the _ioc_access() function,
+// that is always blocking, but can be called in 4 modes:
+//
+// - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address 
+//   as a physical address (as the page tables are not build) and use a polling
+//   policy on the IOC_STATUS register to detect transfer completion, as
+//   hardware interrupts are not activated. This mode is used by the
+//   boot code to load the map.bin file into memory.
+//
+// - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a polling policy on IOC_STATUS
+//   register to detect transfer completion. This mode is used by the boot code
+//   to load the various .elf files into memory.
+//
+// - In KERNEL mode, the _ioc_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a descheduling strategy:
+//   The ISR executed when transfer completes should restart the calling task. 
+//   There is no checking of user access right to the memory buffer.
+//   This mode must be used to access IOC, for an "open" system call.
+//
+// - In USER mode, the _ioc_access() function makes a V2P translation to
+//   compute the buffer physical address, and use a descheduling strategy:
+//   The ISR executed when transfer completes should restart the calling task, 
+//   The user access right to the memory buffer must be checked.
+//   This mode must be used to access IOC, for a "read/write" system call.
+//
+// As the IOC component can be used by several programs running in parallel,
+// the _ioc_lock variable guaranties exclusive access to the device.  The
+// _ioc_read() and _ioc_write() functions use atomic LL/SC to get the lock.
+//
+// The IOMMU can be activated or not:
+// 
+// 1) When the IOMMU is used, a fixed size 2Mbytes vseg is allocated to 
+// the IOC peripheral, in the I/O virtual space, and the user buffer is
+// dynamically remapped in the IOMMU page table. The corresponding entry 
+// in the IOMMU PT1 is defined by the kernel _ioc_iommu_ix1 variable.
+// The number of pages to be unmapped is stored in the _ioc_npages variable.
+// The number of PT2 entries is dynamically computed and stored in the
+// kernel _ioc_iommu_npages variable. It cannot be larger than 512.
+// The user buffer is unmapped by the _ioc_completed() function when 
+// the transfer is completed.
+//
+// 2/ If the IOMMU is not used, we check that  the user buffer is mapped to a
+// contiguous physical buffer (this is generally true because the user space
+// page tables are statically constructed to use contiguous physical memory).
+//
+// Finally, the memory buffer must fulfill the following conditions:
+// - The buffer must be word aligned, 
+// - The buffer must be mapped in user space for an user access, 
+// - The buffer must be writable in case of (to_mem) access,
+// - The total number of physical pages occupied by the user buffer cannot
+//   be larger than 512 pages if the IOMMU is activated,
+// - All physical pages occupied by the user buffer must be contiguous
+//   if the IOMMU is not activated.
+// An error code is returned if these conditions are not verified.
+///////////////////////////////////////////////////////////////////////////////////
+// The seg_ioc_base virtual base addresses must be defined in giet_vsegs.ld file.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <ioc_driver.h>
+#include <utils.h>
+#include <tty_driver.h>
+#include <iob_driver.h>
+#include <ctx_handler.h>
+#include <mmc_driver.h>
+#include <vmem.h>
+
+#if !defined( USE_IOB )
+# error: You must define USE_IOB in the hard_config.h file
+#endif
+
+#if !defined(GIET_USE_IOMMU) 
+# error: You must define GIET_USE_IOMMU in the giet_config.h file
+#endif
+
+#if (USE_BDV + USE_SPI + USE_HBA) != 1
+# error: You must use only one IOC controller (BDV or SPI or HBA)
+#endif
+
+#if USE_BDV
+# include <bdv_driver.h>
+#endif
+
+#if USE_SPI
+# include <sdc_driver.h>
+#endif
+
+#if USE_HBA
+# include <hba_driver.h>
+#endif
+
+
+#define in_unckdata __attribute__((section (".unckdata")))
+
+///////////////////// IOC global variables
+
+in_unckdata unsigned int _ioc_lock = 0;
+in_unckdata unsigned int _ioc_status = 0;
+in_unckdata volatile unsigned int _ioc_gtid;
+in_unckdata volatile unsigned int _ioc_iommu_ix1 = 0;
+in_unckdata volatile unsigned int _ioc_iommu_npages; 
+
+///////////////////////////////////////////////////////////////////////////////
+//      _ioc_access()
+// This function transfer data between a memory buffer and the block device.
+// The buffer lentgth is (count*block_size) bytes.
+// Arguments are:
+// - to_mem     : from external storage to memory when non 0.
+// - kernel     : kernel buffer with identity mapping when non 0. 
+// - lba        : first block index on the external storage.
+// - buf_vaddr  : virtual base address of the memory buffer.
+// - count      : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+static unsigned int _ioc_access( unsigned int to_mem,
+                                 unsigned int mode,
+                                 unsigned int lba,
+                                 unsigned int buf_vaddr,
+                                 unsigned int count) 
+{
+
+#if GIET_DEBUG_IOC_DRIVER
+_tty_get_lock( 0 );
+_puts("\n[IOC DEBUG] Enter _ioc_access() at cycle ");
+_putd( _get_proctime() );
+_puts(" for processor ");
+_putd( _get_procid() );
+_puts("\n - mode    = ");
+_putd( mode );
+_puts("\n - vaddr   = ");
+_putx( buf_vaddr );
+_puts("\n - sectors = ");
+_putd( count );
+_puts("\n - lba     = ");
+_putx( lba );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    unsigned int error;            // return value
+    unsigned int pt_vbase;         // page table vbase address
+    unsigned int vpn_min;          // first virtuel page index covering buffer
+    unsigned int vpn_max;          // last virtual page index covering buffer
+    unsigned int vpn;              // current virtual page index
+    unsigned int ppn;              // physical page number
+    unsigned int flags;            // page protection flags
+    unsigned int ix2;              // page index in IOMMU PT1 page table
+    unsigned int ppn_first;        // first physical page number for user buffer
+    unsigned int buf_xaddr = 0;    // user buffer virtual address in IO space (if IOMMU)
+    paddr_t      buf_paddr = 0;    // user buffer physical address (if no IOMMU),
+
+    // check buffer alignment
+    if ((unsigned int) buf_vaddr & 0x3)
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _ioc_access() : buffer not word aligned\n");
+        _tty_release_lock( 0 );
+        return 1; 
+    }
+
+    unsigned int length = count << 9;  // count * 512 bytes
+
+    // computing target buffer physical address
+    if ( mode == IOC_BOOT_PA_MODE )                // identity mapping
+    {
+        buf_paddr = (paddr_t)buf_vaddr;
+    }
+    else                                           // V2P translation
+    {
+        // get page table virtual address
+        pt_vbase = _get_context_slot(CTX_PTAB_ID);
+        vpn_min = buf_vaddr >> 12;
+        vpn_max = (buf_vaddr + length - 1) >> 12;
+
+        // loop on all virtual pages covering the user buffer
+        for (vpn = vpn_min, ix2 = 0 ; 
+             vpn <= vpn_max ; 
+             vpn++, ix2++ ) 
+        {
+            // get ppn and flags for each vpn
+            unsigned int ko = _v2p_translate( (page_table_t*)pt_vbase,
+                                              vpn,
+                                              &ppn,
+                                              &flags);
+            // check access rights
+            if ( ko )
+            {
+                _tty_get_lock( 0 );
+                _puts("\n[GIET ERROR] in _ioc_access() : buffer unmapped\n");
+                _tty_release_lock( 0 );
+                return 1; 
+            }
+
+            if ( (mode == IOC_USER_MODE) && ((flags & PTE_U) == 0) )
+            {
+                _tty_get_lock( 0 );
+                _puts("\n[GIET ERROR] in _ioc_access() : buffer not user accessible\n");
+                _tty_release_lock( 0 );
+                return 1; 
+            }
+
+            if ( ((flags & PTE_W) == 0 ) && to_mem )
+            {
+                _tty_get_lock( 0 );
+                _puts("\n[GIET ERROR] in _ioc_access() : buffer not writable\n");
+                _tty_release_lock( 0 );
+                return 1; 
+            }
+
+            // save first ppn value
+            if (ix2 == 0) ppn_first = ppn;
+
+#if GIET_USE_IOMMU 
+ 
+            // check buffer length < 2 Mbytes
+            if (ix2 > 511) // check buffer length < 2 Mbytes
+            {
+                _tty_get_lock( 0 );
+                _puts("\n[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n");
+                _tty_release_lock( 0 );
+                return 1; 
+            }
+            // map the physical page in IOMMU page table
+            _iommu_add_pte2( _ioc_iommu_ix1,    // PT1 index
+                             ix2,               // PT2 index
+                             ppn,               // Physical page number    
+                             flags );           // Protection flags
+
+            // compute user buffer virtual adress in IO space
+            buf_xaddr = (_ioc_iommu_ix1) << 21 | (buf_vaddr & 0xFFF);
+
+#else
+
+            // check that physical pages are contiguous
+            if ((ppn - ppn_first) != ix2) 
+            {
+                _tty_get_lock( 0 );
+                _puts("[GIET ERROR] in _ioc_access() : split physical buffer\n");
+                _tty_release_lock( 0 );
+                return 1; 
+            }
+
+            // compute user buffer physical adress
+            buf_paddr = (((paddr_t)ppn_first) << 12) | (buf_vaddr & 0xFFF);
+#endif            
+
+        } // end for vpn
+    }
+
+#if GIET_USE_IOMMU 
+
+    // register the number of pages to be unmapped in IOMMU
+    _ioc_iommu_npages = (vpn_max - vpn_min) + 1;
+
+#endif
+
+    if ( to_mem ) // memory write : invalidate data caches 
+    {
+        // L1 cache
+        if ( GIET_NO_HARD_CC ) _dcache_buf_invalidate((void *) buf_vaddr, length);
+
+        // L2 cache (only if IOB used)
+        if ( USE_IOB ) _memc_inval( buf_paddr, length );
+    }
+    else         // memory read : update data caches
+    {
+        // L1 cache : nothing to do if L1 write-through
+
+        // L2 cache (only if IOB used)
+        if ( USE_IOB ) _memc_sync( buf_paddr, length );
+    }
+
+    if ( GIET_USE_IOMMU ) buf_paddr = (paddr_t) buf_xaddr;
+
+#if   USE_BDV
+    if (to_mem) error = _bdv_read (mode, lba, buf_paddr, count);
+    else        error = _bdv_write(mode, lba, buf_paddr, count);
+#elif USE_SPI
+    if (to_mem) error = _sdc_read (mode, lba, buf_paddr, count);
+    else        error = _sdc_write(mode, lba, buf_paddr, count);
+#elif USE_HBA
+    if (to_mem) error = _hba_read (mode, lba, buf_paddr, count);
+    else        error = _hba_write(mode, lba, buf_paddr, count);
+#endif
+
+    return error;
+} // end _ioc_access()
+
+///////////////////////////////////////////////////////////////////////////////
+//       _ioc_init()
+// This function cheks block size, and activates the IOC interrupts.
+// Return 0 for success.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _ioc_init( unsigned int channel )
+{
+#if   USE_BDV
+    return _bdv_init( channel );
+#elif USE_SPI
+    return _sdc_init( channel );
+#elif USE_HBA
+    return _hba_init( channel );
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _ioc_read()
+// Transfer data from the block device to a memory buffer. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _ioc_read( unsigned int mode,  
+                        unsigned int lba, 
+                        void*        buffer, 
+                        unsigned int count) 
+{
+    return _ioc_access( 1,        // read access
+                        mode,  
+                        lba,
+                        (unsigned int) buffer,
+                        count );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _ioc_write()
+// Transfer data from a memory buffer to the block device. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _ioc_write( unsigned int mode,  
+                         unsigned int lba, 
+                         const void*  buffer, 
+                         unsigned int count ) 
+{
+    return _ioc_access( 0,        // write access
+                        mode,  
+                        lba,
+                        (unsigned int) buffer,
+                        count );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _ioc_get_status()
+// This function returns in the status variable, the transfert status, and
+// acknowledge the IRQ if the IOC controler is not busy.
+// Returns 0 if success, > 0 if error
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _ioc_get_status( unsigned int  channel,
+                              unsigned int* status )
+{
+#if   USE_BDV
+    return _bdv_get_status(channel, status);
+#elif USE_SPI
+    return _sdc_get_status(channel, status);
+#elif USE_HBA
+    return _hba_get_status(channel, status);
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//     _ioc_get_block_size()
+// This function returns the block_size with which the IOC has been configured.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _ioc_get_block_size() 
+{
+#if   USE_BDV
+    return _bdv_get_block_size();
+#elif USE_SPI
+    return _sdc_get_block_size();
+#elif USE_HBA
+    return _hba_get_block_size();
+#endif
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.h	(revision 283)
@@ -0,0 +1,90 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : ioc_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_IOC_DRIVERS_H_
+#define _GIET_IOC_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// IOC (vci_block device) registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum IOC_registers 
+{
+    BLOCK_DEVICE_BUFFER,
+    BLOCK_DEVICE_LBA,
+    BLOCK_DEVICE_COUNT,
+    BLOCK_DEVICE_OP,
+    BLOCK_DEVICE_STATUS,
+    BLOCK_DEVICE_IRQ_ENABLE,
+    BLOCK_DEVICE_SIZE,
+    BLOCK_DEVICE_BLOCK_SIZE,
+    BLOCK_DEVICE_BUFFER_EXT,
+};
+enum IOC_operations 
+{
+    BLOCK_DEVICE_NOOP,
+    BLOCK_DEVICE_READ,
+    BLOCK_DEVICE_WRITE,
+};
+enum IOC_status
+{
+    BLOCK_DEVICE_IDLE,
+    BLOCK_DEVICE_BUSY,
+    BLOCK_DEVICE_READ_SUCCESS,
+    BLOCK_DEVICE_WRITE_SUCCESS,
+    BLOCK_DEVICE_READ_ERROR,
+    BLOCK_DEVICE_WRITE_ERROR,
+    BLOCK_DEVICE_ERROR,
+};
+enum IOC_driver_modes
+{
+    IOC_BOOT_PA_MODE,  // No V2P translation / Polling IOC_STATUS / no access checking
+    IOC_BOOT_VA_MODE,  // V2P translation    / Polling IOC_STATUS / no access checking
+    IOC_KERNEL_MODE,   // V2P translation    / Descheduling + IRQ / no access checking
+    IOC_USER_MODE,     // V2P translation    / Descheduling + IRQ / access checking
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// IOC access functions and variables (vci_block_device)
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _ioc_lock;
+extern unsigned int _ioc_status;
+extern volatile unsigned int _ioc_gtid;
+extern volatile unsigned int _ioc_iommu_ix1;
+extern volatile unsigned int _ioc_iommu_npages; 
+
+extern unsigned int _ioc_init( unsigned int channel );
+
+extern unsigned int _ioc_write( unsigned int mode,
+                                unsigned int lba, 
+                                const void*  buffer, 
+                                unsigned int count );
+
+extern unsigned int _ioc_read(  unsigned int mode,
+                                unsigned int lba, 
+                                void*        buffer,
+                                unsigned int count );
+
+extern unsigned int _ioc_get_status( unsigned int  channel,
+                                     unsigned int* status );
+
+extern unsigned int _ioc_get_block_size();
+
+///////////////////////////////////////////////////////////////////////////////////
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/mmc_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/mmc_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/mmc_driver.c	(revision 283)
@@ -0,0 +1,140 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : mmc_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The mmc_driver.c and mmc_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the vci_mem_cache component used in the TSAR architecture.
+//
+// This component is replicated in all clusters, and can be accessed through 
+// a configuration interface as a set of uncached, memory mapped registers.
+///////////////////////////////////////////////////////////////////////////////////
+// The (virtual) base address of the associated segment is:
+//
+//       seg_mmc_base + cluster_id * vseg_cluster_increment
+//
+// The seg_mmc_base and vseg_cluster_increment values must be defined 
+// in the giet_vsegs.ld file.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <mmc_driver.h>
+#include <tty_driver.h>
+#include <utils.h>
+
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////
+// _memc_inval()
+// This function invalidates all cache lines covering a memory buffer defined
+// by the physical base address, and the length.
+// The buffer address MSB are used to compute the cluster index.
+///////////////////////////////////////////////////////////////////////////////////
+void _memc_inval( paddr_t      buf_paddr,
+                  unsigned int buf_length )
+{
+    // compute cluster coordinates
+    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
+    unsigned int x          = cluster_xy >> Y_WIDTH;
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+
+    // parameters checking 
+    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
+    {
+        _puts("\n[GIET ERROR] in _memc_inval() : illegal cluster index[");
+        _putd( x );
+        _puts(",");
+        _putd( y );
+        _puts("]\n");
+        _puts("   - paddr      = ");
+        _putl( buf_paddr );
+        _puts("\n   - cluster_xy = ");
+        _putx( cluster_xy );
+        _puts("\n");
+        _exit();
+    }
+
+    unsigned int* mmc_address = (unsigned int*)((unsigned int)&seg_mmc_base + 
+                                (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    // get the hard lock protecting exclusive access to MEMC
+    while ( mmc_address[MEMC_LOCK] ) { asm volatile("nop"); }
+
+    // write inval arguments
+    mmc_address[MEMC_ADDR_LO]    = (unsigned int)buf_paddr;
+    mmc_address[MEMC_ADDR_HI]    = (unsigned int)(buf_paddr>>32);
+    mmc_address[MEMC_BUF_LENGTH] = buf_length;
+    mmc_address[MEMC_CMD_TYPE]   = MEMC_CMD_INVAL;
+
+    // release the lock 
+    mmc_address[MEMC_LOCK] = 0;
+}
+///////////////////////////////////////////////////////////////////////////////////
+// _memc_sync()
+// This function copies to external RAM all cache lines covering a memory buffer 
+// defined by the physical base address, and the length, if they are dirty.
+// The buffer address MSB are used to compute the cluster index.
+///////////////////////////////////////////////////////////////////////////////////
+void _memc_sync( paddr_t      buf_paddr,
+                 unsigned int buf_length )
+{
+    // compute cluster coordinates
+    unsigned int cluster_xy = (unsigned int)(buf_paddr>>(40-X_WIDTH-Y_WIDTH));
+    unsigned int x          = cluster_xy >> Y_WIDTH;
+    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
+
+    // parameters checking 
+    if ( (x >= X_SIZE) || (y >= Y_SIZE) )
+    {
+        _puts("\n[GIET ERROR] in _memc_sync() : illegal cluster index[");
+        _putd( x );
+        _puts(",");
+        _putd( y );
+        _puts("]\n");
+        _puts("   - paddr      = ");
+        _putl( buf_paddr );
+        _puts("\n   - cluster_xy = ");
+        _putx( cluster_xy );
+        _puts("\n");
+        _exit();
+    }
+
+    unsigned int * mmc_address = (unsigned int *) ((unsigned int)&seg_mmc_base + 
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    // get the hard lock protecting exclusive access to MEMC
+    while ( mmc_address[MEMC_LOCK] ) { asm volatile("nop"); }
+
+    // write inval arguments
+    mmc_address[MEMC_ADDR_LO]    = (unsigned int)buf_paddr;
+    mmc_address[MEMC_ADDR_HI]    = (unsigned int)(buf_paddr>>32);
+    mmc_address[MEMC_BUF_LENGTH] = buf_length;
+    mmc_address[MEMC_CMD_TYPE]   = MEMC_CMD_SYNC;
+
+    // release the lock protecting MEMC
+    mmc_address[MEMC_LOCK] = 0;
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/mmc_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/mmc_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/mmc_driver.h	(revision 283)
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : mmc_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_MMC_DRIVERS_H_
+#define _GIET_MMC_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// TSAR Memory Cache configuration registers offsets and commands
+///////////////////////////////////////////////////////////////////////////////////
+
+enum SoclibMemCacheConfigRegs
+{
+    MEMC_LOCK,
+    MEMC_ADDR_LO,
+    MEMC_ADDR_HI,
+    MEMC_BUF_LENGTH,
+    MEMC_CMD_TYPE
+};
+
+enum SoclibMemCacheConfigCmd
+{
+    MEMC_CMD_NOP,
+    MEMC_CMD_INVAL,
+    MEMC_CMD_SYNC
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// MEMC access functions (for TSAR architecture)
+///////////////////////////////////////////////////////////////////////////////////
+
+extern void _memc_inval( unsigned long long buf_paddr, 
+                         unsigned int buf_length );
+
+extern void _memc_sync(  unsigned long long buf_paddr, 
+                         unsigned int buf_length);
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/mwr_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/mwr_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/mwr_driver.c	(revision 283)
@@ -0,0 +1,100 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : mwr_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The mwmr_driver.c and mwmr_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the SoClib vci_mwmr_controller component.
+// 
+// This peripheral can be replicated (at most one component per cluster).
+///////////////////////////////////////////////////////////////////////////////////
+// The (virtual) base address of the associated segment is:
+//
+//       seg_mwr_base + cluster_xy * vseg_cluster_increment
+//
+// The seg_mwr_base and vseg_cluster_increment values must be defined 
+// in the giet_vsegs.ld file.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <mwr_driver.h>
+#include <utils.h>
+
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////
+//    _mwr_hw_init()
+// This function initializes one MWMR controller channel (i.e. one coprocessor
+// port) in a given cluster.
+// - cluster_xy    : cluster index
+// _ port_id       : port index
+// - way           : direction (to_coproc/from_coproc)
+// - channel_pbase : physical base address of the MWMR channel 
+// TODO : The MWMR controler should be modified to support 40 bits addresses...
+//        Introduce a MWMR_CONFIG_PADDR_EXT register in the MWMR coprocessor
+//////////////////////////////////////////////////////////////////////////////////
+// Returns 0 if success, returns > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _mwr_hw_init( unsigned int           cluster_xy, 
+                           unsigned int           port_id, 
+                           unsigned int           from_coproc,
+                           paddr_t                channel_pbase ) 
+{
+    _puts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");
+    _exit();
+
+/*
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                    return 1; 
+    if (y >= Y_SIZE)                    return 1; 
+
+    // compute base address
+    unsigned int* mwr_address = (unsigned int*) ((unsigned int)&seg_mwr_base + 
+                                 (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    unsigned int lsb = (unsigned int)channel_pbase;
+    unsigned int msb = (unsigned int)(channel_pbase>>32);
+
+    // get depth and width from channel itself
+    unsigned int depth = _physical_read( channel_pbase + 16 );
+    unsigned int width = _physical_read( channel_pbase + 20 );
+
+    // initializes and launches mwmr controler
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_WAY]  = from_coproc;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_FIFO_NO]   = port_id;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_WIDTH]     = width;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DEPTH]     = depth;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_STATUS]    = lsb;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_DATA]      = lsb + 24;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_EXT]       = msb;
+    mwr_address[port_id * MWMR_SPAN + MWMR_CONFIG_RUNNING]   = 1;
+*/
+    return 0;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/mwr_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/mwr_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/mwr_driver.h	(revision 283)
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : mwr_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_MWR_DRIVERS_H_
+#define _GIET_MWR_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// MWMR controler registers offsets 
+///////////////////////////////////////////////////////////////////////////////////
+
+enum SoclibMwmrRegisters 
+{
+    MWMR_IOREG_MAX = 16,
+    MWMR_RESET = MWMR_IOREG_MAX,
+    MWMR_CONFIG_FIFO_WAY,
+    MWMR_CONFIG_FIFO_NO,
+    MWMR_CONFIG_STATUS,
+    MWMR_CONFIG_DEPTH,
+    MWMR_CONFIG_BUFFER_ADDR,
+    MWMR_CONFIG_RUNNING,
+    MWMR_CONFIG_WIDTH,
+    MWMR_CONFIG_DATA,
+    MWMR_CONFIG_EXT,
+    /***/
+    MWMR_SPAN,
+};
+
+enum SoclibMwmrWay 
+{
+    MWMR_TO_COPROC,
+    MWMR_FROM_COPROC,
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// MWMR controller access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _mwr_hw_init( unsigned int           cluster_xy, 
+                                  unsigned int           port_id, 
+                                  unsigned int           from_coproc,
+                                  unsigned long long     channel_pbase);
+
+///////////////////////////////////////////////////////////////////////////////////
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/nic_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/nic_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/nic_driver.c	(revision 283)
@@ -0,0 +1,123 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : nic_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The nic_driver.c and nic_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the vci_multi_nic component.
+// 
+// It can exist only one network controller in the architecture, but this
+// component supports several channels.
+//
+// It can be accessed directly by software with memcpy(),
+// or it can be accessed through the vci_chbuf_dma component:
+//  
+// The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to
+// implement the transfer between a data buffer (user space) and the NIC
+// buffer (kernel space). They are blocking until completion of the transfer.
+//
+// The _nic_cma_*_init() and _nic_cma_stop() functions use the VciChbufDma component 
+// to transfer a flow of packets from the NIC RX hard chbuf (two containers) 
+// to an user RX chbuf (two containers), and to transfer another flow of packets
+// from an user TX chbuf (two containers) to the NIC TX chbuf (two containers).
+// One NIC channel and two CMA channels must be allocated to the task 
+// in the mapping_info data structure.
+//////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <nic_driver.h>
+#include <utils.h>
+
+#if !defined(GIET_USE_IOMMU) 
+# error: You must define GIET_USE_IOMMU in the giet_config.h file
+#endif
+
+#if !defined(NB_NIC_CHANNELS)
+# error: You must define NB_NIC_CHANNELS in the hard_config.h file 
+#endif
+
+#if ( NB_NIC_CHANNELS > 8 )
+# error: NB_NIC_CHANNELS cannot be larger than 8
+#endif
+
+#if !defined(NB_CMA_CHANNELS)
+# error: You must define NB_CMA_CHANNELS in the hard_config.h file 
+#endif
+
+#if ( NB_CMA_CHANNELS > 8 )
+# error: NB_CMA_CHANNELS cannot be larger than 8
+#endif
+
+#if !defined( USE_IOB )
+# error: You must define USE_IOB in the hard_config.h file
+#endif
+
+#define in_unckdata __attribute__((section (".unckdata")))
+
+//////////////////////////////////////////////////////////////////////////////////
+// _nic_sync_write()
+// Transfer data from an memory buffer to the NIC device using a memcpy.
+// - buffer : base address of the memory buffer.
+// - length : number of bytes to be transfered.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _nic_sync_write( const void*    buffer,
+                              unsigned int   length ) 
+{
+    _puts("[GIET ERROR] _nic_sync_write function not implemented\n");
+    _exit();
+
+    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
+    // memcpy((void *) nic_address, (void *) buffer, length);
+    return 0;
+}
+//////////////////////////////////////////////////////////////////////////////////
+// _nic_sync_read()
+// Transfer data from the NIC device to a memory buffer using a memcpy. 
+// - buffer : base address of the memory buffer.
+// - length : number of bytes to be transfered.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _nic_sync_read( const void*    buffer, 
+                             unsigned int   length ) 
+{
+    _puts("[GIET ERROR] _nic_sync_read function not implemented\n");
+    _exit();
+
+    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
+    // memcpy((void *) buffer, (void *) nic_address, length);
+    return 0;
+}
+//////////////////////////////////////////////////////////////////////////////////
+// _nic_cma_start()
+// Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _nic_cma_start( )
+{
+    _puts("[GIET ERROR] _nic_cma_start function not implemented\n");
+    _exit();
+
+    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
+    return 0;
+}
+//////////////////////////////////////////////////////////////////////////////////
+// _nic_cma_stop()
+// Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+unsigned int _nic_cma_stop()
+{
+    _puts("[GIET ERROR] _nic_cma_stop function not implemented\n");
+    _exit();
+
+    // unsigned char* nic_address = (unsigned char *) &seg_nic_base;
+    return 0;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/nic_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/nic_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/nic_driver.h	(revision 283)
@@ -0,0 +1,37 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : nic_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_NIC_DRIVERS_H_
+#define _GIET_NIC_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// NIC device access functions  (vci_multi_nic)
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _nic_sync_write( const void*  buffer, 
+                                     unsigned int length );
+
+extern unsigned int _nic_sync_read(  const void*  buffer, 
+                                     unsigned int length );
+
+extern unsigned int _nic_cma_start();
+
+extern unsigned int _nic_cma_stop();
+
+///////////////////////////////////////////////////////////////////////////////////
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/sdc_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/sdc_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/sdc_driver.c	(revision 283)
@@ -0,0 +1,490 @@
+/**
+ * \file    : sdc_driver.c
+ * \date    : 30 August 2012
+ * \author  : Cesar Fuguet
+ *
+ * This file defines the driver of a SD Card device using an SPI controller
+ */
+
+#include <sdc_driver.h>
+#include <utils.h>
+
+#define SYSCLK_FREQ           50000000
+#define SDCARD_RESET_ITER_MAX 4
+
+static struct sdcard_dev sdcard;
+static struct spi_dev*   spi;
+
+/**
+ * \return  void
+ *
+ * \brief   Enable SD Card select signal
+ */
+static void _sdc_enable()
+{
+    spi_ss_assert(sdcard.spi, sdcard.slave_id);
+}
+
+/**
+ * \return  void
+ *
+ * \brief   Disable SD Card select signal
+ */
+static void _sdc_disable()
+{
+    spi_ss_deassert(sdcard.spi, sdcard.slave_id);
+}
+
+/**
+ * \param   tick_count: SD Card clock ticks number
+ *
+ * \return  void
+ *
+ * \brief   Enable SD Card clock
+ *          The tick count is byte measured (1 tick, 8 clock)
+ */
+static void _sdc_gen_tick(unsigned int tick_count)
+{
+    register int i = 0;
+    while(i++ < tick_count) spi_put_tx(sdcard.spi, 0xFF, 0);
+}
+
+/**
+ * \param   lba : Position where the block device access
+ *                pointer must be move
+ *
+ * \return  void
+ *
+ * \brief   Change block device access pointer position
+ *  
+ * The block device access pointer is relocated in terms of blocks
+ */
+void _sdc_lseek(unsigned int lba)
+{
+    sdcard.access_pointer = sdcard.block_length * lba;
+}
+
+/**
+ * \return  char from the SD card
+ *
+ * \brief   Get a byte from the SD Card
+ */
+static unsigned char _sdc_receive_char()
+{
+    _sdc_gen_tick(1);
+
+    return spi_get_rx(sdcard.spi, 0);
+}
+
+/**
+ * \return  sdcard response
+ *
+ * \brief   Wait for a valid response after the send of a command
+ *          This function can return if one of the next two conditions are true:
+ *           1. Bit valid received
+ *           2. Timeout (not valid bit received after SDCARD_COMMAND_TIMEOUT
+ *              wait ticks)
+ */
+static unsigned char _sdc_wait_response()
+{
+    unsigned char sdcard_rsp;
+    register int  iter;
+
+    iter       = 0;
+    sdcard_rsp = _sdc_receive_char();
+    while (
+            (iter < SDCARD_COMMAND_TIMEOUT) &&
+            !SDCARD_CHECK_R1_VALID(sdcard_rsp)
+          )
+    {
+        sdcard_rsp = _sdc_receive_char();
+        iter++;
+    }
+
+    return sdcard_rsp;
+}
+
+/**
+ * \return  void
+ *
+ * \brief   Wait data block start marker
+ */
+static void _sdc_wait_data_block()
+{
+	while (_sdc_receive_char() != 0xFE);
+}
+
+/**
+ * \param   index   : SD card CMD index
+ * \param   app     : Type of command, 0 for normal command or 1 for
+ *                    application specific
+ * \param   args    : SD card CMD arguments
+ *
+ * \return  response first byte
+ *
+ * \brief   Send command to the SD card
+ */
+static int _sdc_send_command ( int      index,
+                               int      app  ,
+                               void *   args ,
+                               unsigned crc7 )
+{
+    unsigned char sdcard_rsp;
+    unsigned char * _args;
+
+    _sdc_gen_tick(5);  
+
+    if (app == SDCARD_ACMD)
+    {
+        spi_put_tx(sdcard.spi, 0x40 | 55         , 0 );/* CMD and START bit */
+        spi_put_tx(sdcard.spi, 0x00              , 0 );/* Argument[0]       */
+        spi_put_tx(sdcard.spi, 0x00              , 0 );/* Argument[1]       */
+        spi_put_tx(sdcard.spi, 0x00              , 0 );/* Argument[2]       */
+        spi_put_tx(sdcard.spi, 0x00              , 0 );/* Argument[3]       */
+        spi_put_tx(sdcard.spi, 0x01 | (crc7 << 1), 0 );/* END bit           */
+
+        sdcard_rsp = _sdc_wait_response();
+        if (SDCARD_CHECK_R1_ERROR(sdcard_rsp))
+        {
+            return sdcard_rsp;        
+        }
+    }
+
+    _args = (unsigned char *) args;
+
+    _sdc_gen_tick(1);  
+
+    spi_put_tx(sdcard.spi, 0x40 | index      , 0 );
+    spi_put_tx(sdcard.spi, _args[0]          , 0 );
+    spi_put_tx(sdcard.spi, _args[1]          , 0 );
+    spi_put_tx(sdcard.spi, _args[2]          , 0 );
+    spi_put_tx(sdcard.spi, _args[3]          , 0 );
+    spi_put_tx(sdcard.spi, 0x01 | (crc7 << 1), 0 );
+
+    return _sdc_wait_response();
+}
+
+static int _sdc_open( unsigned int channel )
+{
+	unsigned char args[4];
+	unsigned char sdcard_rsp;
+	unsigned int  iter, ersp;
+
+	sdcard.spi      = spi;
+	sdcard.slave_id = channel;
+
+	/* 
+	* Supply SD card ramp up time (min 74 cycles)
+	*/
+	_sdc_gen_tick(10);
+
+	/* 
+	* Assert slave select signal
+	* Send CMD0 (Reset Command)
+	* Deassert slave select signal
+	*/
+	_sdc_enable();
+
+	args[0] = 0;
+	args[1] = 0;
+	args[2] = 0;
+	args[3] = 0;
+	sdcard_rsp = _sdc_send_command(0, SDCARD_CMD, args, 0x4A);
+	if ( sdcard_rsp != 0x01 )
+	{
+
+		_puts("card CMD0 failed ");
+		return sdcard_rsp;
+	}
+
+	_sdc_disable();
+	/*
+	 * send CMD8. If card is pre-v2, It will reply with illegal command.
+	 * Otherwise we announce sdhc support.
+	 */
+	_sdc_enable();
+	args[0] = 0;
+	args[1] = 0;
+	args[2] = 0x01;
+	args[3] = 0x01;
+	sdcard_rsp = _sdc_send_command(8, SDCARD_CMD, args, 0x63);
+	if (!SDCARD_CHECK_R1_VALID(sdcard_rsp)) {
+		_puts("card CMD8 failed ");
+		return sdcard_rsp;
+	}
+	if (!SDCARD_CHECK_R1_ERROR(sdcard_rsp)) {
+		/* no error, command accepted. get whole reply */
+		ersp = _sdc_receive_char();
+		ersp = (ersp << 8) | _sdc_receive_char();
+		ersp = (ersp << 8) | _sdc_receive_char();
+		ersp = (ersp << 8) | _sdc_receive_char();
+		if ((ersp & 0xffff) != 0x0101) {
+			/* voltage mismatch */
+			_puts("card CMD8 mismatch: ");
+			_putx(ersp);
+			return sdcard_rsp;
+		}
+		_puts("v2 or later ");
+		sdcard.sdhc = 1;
+	} else if ((sdcard_rsp & SDCARD_R1_ILLEGAL_CMD) == 0) {
+		/* other error */
+		_puts("card CMD8 error ");
+		return sdcard_rsp;
+	} else {
+		sdcard.sdhc = 0;
+	}
+	_sdc_disable();
+	/* send CMD41, enabling the card */
+	_sdc_enable();
+	args[0] = sdcard.sdhc ? 0x40: 0;
+	args[1] = 0;
+	args[2] = 0;
+	args[3] = 0;
+
+	iter = 0;
+	while( iter++ < SDCARD_COMMAND_TIMEOUT )
+	{
+		sdcard_rsp = _sdc_send_command(41, SDCARD_ACMD, args, 0x00);
+		if( sdcard_rsp == 0x01 )
+		{
+			continue;
+		}
+
+		break;
+	}
+
+	_sdc_disable();
+	if (sdcard_rsp) {
+		_puts("SD ACMD41 failed ");
+		return sdcard_rsp;
+	}
+	if (sdcard.sdhc != 0) {
+		/* get the card capacity to see if it's really HC */
+		_sdc_enable();
+		args[0] = sdcard.sdhc ? 0x40: 0;
+		args[1] = 0;
+		args[2] = 0;
+		args[3] = 0;
+        sdcard_rsp = _sdc_send_command(58, SDCARD_CMD, args, 0x00);
+		if (sdcard_rsp) {
+			_puts("SD CMD58 failed ");
+			return sdcard_rsp;
+		}
+		ersp = _sdc_receive_char();
+		ersp = (ersp << 8) | _sdc_receive_char();
+		ersp = (ersp << 8) | _sdc_receive_char();
+		ersp = (ersp << 8) | _sdc_receive_char();
+		if (ersp & 0x40000000) {
+			_puts("SDHC ");
+		} else {
+			sdcard.sdhc = 0;
+		}
+		_sdc_disable();
+	}
+	_puts("card detected ");
+	return 0;
+}
+
+static unsigned int _sdc_set_block_size(unsigned int len)
+{
+    unsigned char args[4];
+    unsigned char sdcard_rsp;
+    register int i;
+
+    /*
+     * For now, supported block size is 512 bytes
+     */
+    if (len != 512) return 1;
+
+    /*
+     * When using high capacity SDCARD, the block_length is not a number of bytes
+     * but a number of blocks (transfer unit)
+     */
+    if (sdcard.sdhc)
+    {
+        sdcard.block_length = len / 512;
+        return 0;
+    }
+
+    for (i = 0; i < 4; i++)
+    {
+        args[i] = (len >> (32 - (i+1)*8)) & 0xFF;
+    }
+
+    _sdc_enable();
+
+    sdcard_rsp = _sdc_send_command(16, SDCARD_CMD, args, 0x00);
+    if ( SDCARD_CHECK_R1_ERROR(sdcard_rsp) )
+    {
+        _sdc_disable();
+        return sdcard_rsp;
+    }
+
+    _sdc_disable();
+
+    sdcard.block_length = len;
+
+	return 0;
+}
+
+unsigned int _sdc_init( unsigned int channel )
+{
+    spi = (struct spi_dev*) &seg_ioc_base;
+
+    /**
+     * Initializing the SPI controller
+     */
+    _spi_init (
+        spi           ,
+        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;
+    unsigned char sdcard_rsp;
+    unsigned int i;
+
+    while(1)
+    {
+        _puts("Trying to initialize SD card... ");
+
+        sdcard_rsp = _sdc_open( channel );
+        if (sdcard_rsp == 0)
+        {
+            _puts("OK\n");
+            break;
+        }
+
+        _puts("KO\n");
+
+        for (i = 0; i < 1000; i++);
+
+        if (++iter >= SDCARD_RESET_ITER_MAX)
+        {
+            _puts("\nERROR: During SD card reset to IDLE state\n"
+                 "/ card response = ");
+            _putx(sdcard_rsp);
+            _puts("\n");
+            _exit();
+        }
+    }
+
+    /**
+     * Set the block length of the SD Card
+     */
+    sdcard_rsp = _sdc_set_block_size(512);
+    if (sdcard_rsp)
+    {
+        _puts("ERROR: During SD card blocklen initialization\n");
+        _exit();
+    }
+
+    /**
+     * Incrementing SDCARD clock frequency for normal function
+     */
+    _spi_init (
+        spi         ,
+        10000000    , /**< SPI_clk 10 Mhz */
+        SYSCLK_FREQ , /**< Sys_clk        */
+        -1          , /**< Charlen: 8     */
+        -1          ,
+        -1
+    );
+
+    _puts("Finish block device initialization\n\r");
+
+    return 0;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//     _sdc_read()
+// Transfer data from the block device to a memory buffer. 
+// - mode     : BOOT / KERNEL / USER
+// - lba      : first block index on the block device
+// - buffer   : base address of the memory buffer (must be word aligned)
+// - count    : number of blocks to be transfered.
+// Returns 0 if success, > 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+unsigned int _sdc_read( unsigned int mode,
+                        unsigned int lba,
+                        paddr_t      buffer,
+                        unsigned int count )
+{
+    unsigned char args[4];
+    unsigned char sdcard_rsp;
+    unsigned int i;
+    unsigned int curr = lba;
+    unsigned int last = lba + count;
+
+    for ( ; curr < last ; curr++ )
+    {
+        _sdc_lseek(curr);
+
+        for (i = 0; i < 4; i++)
+        {
+            args[i] = (sdcard.access_pointer >> (32 - (i+1)*8)) & 0xFF;
+        }
+
+        _sdc_enable();
+
+        sdcard_rsp = _sdc_send_command(17, SDCARD_CMD, args, 0x00);
+        if ( SDCARD_CHECK_R1_ERROR(sdcard_rsp) )
+        {
+            _sdc_disable();
+            return sdcard_rsp;
+        }
+
+        _sdc_wait_data_block();
+
+        if (spi_get_data(sdcard.spi, buffer, 512 ))
+        {
+            _sdc_disable();
+            return 1;
+        }
+
+        /*
+         * Get the CRC16 (comes at the end of the data block)
+         */
+        _sdc_receive_char(); // first byte
+        _sdc_receive_char(); // second byte
+
+        _sdc_disable();
+
+        buffer += 512;
+    }
+
+    return 0;
+}
+
+unsigned int _sdc_write( unsigned int mode,
+                         unsigned int lba,
+                         paddr_t      buffer,
+                         unsigned int count )
+{
+	return 0;
+}
+
+unsigned int _sdc_get_status( unsigned int channel ,
+                              unsigned int* status )
+{
+    return BLOCK_DEVICE_IDLE;
+}
+
+unsigned int _sdc_get_block_size()
+{
+    if (sdcard.sdhc) return sdcard.block_length*512;
+    else             return sdcard.block_length;
+}
+
+
+
+/*
+ * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4
+ */
Index: /branch/giet_vm_ioc_drivers/giet_drivers/sdc_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/sdc_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/sdc_driver.h	(revision 283)
@@ -0,0 +1,126 @@
+/**
+ * \file sdc_driver.h
+ * \date 30 August 2012
+ * \author Cesar fuguet <cesar.fuguet-tortolero@lip6.fr>
+ *
+ * This file defines the driver of a SD Card device using an SPI controller
+ */
+
+#ifndef SDC_DRIVER_H
+#define SDC_DRIVER_H
+
+#include <ioc_driver.h>
+#include <spi_driver.h>
+#include <mapping_info.h>
+
+/**
+ * \brief SD Card type definition
+ */
+struct sdcard_dev
+{ 
+    /** 
+     * SPI controller pointer 
+     */
+    struct spi_dev * spi;
+
+    /**
+     * Block length of the SDCARD
+     */
+    unsigned int block_length;
+
+    /**
+     * Access pointer representing the offset in bytes used
+     * to read or write in the SDCARD.
+     *
+     * \note this driver is for cards SDSD, therefore this offset
+     *       must be multiple of the block length
+     */ 
+    unsigned int access_pointer;
+
+    /**
+     * Slave ID. This ID represents the number of the slave select signal
+     * used in the hardware platform (SPI channel)
+     */
+    int    slave_id;
+
+    /* is the card high capacity ? */
+    int sdhc;
+};
+
+unsigned int _sdc_init( unsigned int channel );
+
+
+unsigned int _sdc_read( unsigned int mode,
+                        unsigned int lba,
+                        paddr_t      buffer,
+                        unsigned int count);
+
+
+unsigned int _sdc_write( unsigned int mode,
+                         unsigned int lba,
+                         paddr_t      buffer,
+                         unsigned int count);
+
+unsigned int _sdc_get_block_size();
+
+unsigned int _sdc_get_status( unsigned int channel ,
+                              unsigned int* status );
+
+
+/**
+ * SD Card constants
+ */
+
+/** Number of retries after an unacknowledge command */
+#define SDCARD_COMMAND_TIMEOUT      100
+
+/** This command is a simple SD commmand */
+#define SDCARD_CMD                  0
+
+/** This is an application specific command */
+#define SDCARD_ACMD                 1
+
+/** The transmition is done in the negative edge of the clock */
+#define SDCARD_TX_NEGEDGE           0
+
+/** The transmition is done in the positive edge of the clock */
+#define SDCARD_TX_POSEDGE           1
+
+/** The reception is done in the negative edge of the clock */
+#define SDCARD_RX_NEGEDGE           0
+
+/** The reception is done in the positive edge of the clock */
+#define SDCARD_RX_POSEDGE           1
+
+/**
+ * SD Card macros
+ */
+
+/** Check if the response is valid */
+#define SDCARD_CHECK_R1_VALID(x)    (~x & SDCARD_R1_RSP_VALID) ? 1 : 0
+
+/**
+ * Check if there is an error in the response
+ *
+ * \note this macro must be used after verify that the response is
+ *       valid
+ */
+#define SDCARD_CHECK_R1_ERROR(x)    ( x & 0x7E)                ? 1 : 0
+
+/**
+ * SD Card Response 1 (R1) format constants
+ */
+#define SDCARD_R1_IN_IDLE_STATE     ( 1 << 0 ) /**< \brief R1 bit 0 */
+#define SDCARD_R1_ERASE_RESET       ( 1 << 1 ) /**< \brief R1 bit 1 */
+#define SDCARD_R1_ILLEGAL_CMD       ( 1 << 2 ) /**< \brief R1 bit 2 */
+#define SDCARD_R1_COM_CRC_ERR       ( 1 << 3 ) /**< \brief R1 bit 3 */
+#define SDCARD_R1_ERASE_SEQ_ERR     ( 1 << 4 ) /**< \brief R1 bit 4 */
+#define SDCARD_R1_ADDRESS_ERR       ( 1 << 5 ) /**< \brief R1 bit 5 */
+#define SDCARD_R1_PARAMETER_ERR     ( 1 << 6 ) /**< \brief R1 bit 6 */
+#define SDCARD_R1_RSP_VALID         ( 1 << 7 ) /**< \brief R1 bit 7 */
+
+#endif
+
+/*
+ * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4
+ */
Index: /branch/giet_vm_ioc_drivers/giet_drivers/sim_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/sim_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/sim_driver.c	(revision 283)
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : sim_driver.c
+// Date     : 23/11/2013
+// Author   : alain greiner / cesar fuguet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The sim_driver.c and sim_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the vci_sim_helper component.
+// There is at most one such component in the architecture.
+///////////////////////////////////////////////////////////////////////////////////
+// The seg_sim_base address must be defined in the giet_vsegs.ld file.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <sim_driver.h>
+#include <utils.h>
+
+////////////////////////////////////////////////////////////////////////////////
+// _sim_helper_access()
+// Accesses the Simulation Helper Component.
+//
+// If the access is on a writable register (except SIMHELPER_PAUSE_SIM),
+// the simulation will stop.
+// If the access is on a readable register, value is written in retval buffer.
+// Returns 0 on success, 1 on failure.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _sim_helper_access( unsigned int register_index,
+                                 unsigned int value,
+                                 unsigned int * retval) 
+{
+    unsigned int* sim_helper_address = (unsigned int*)&seg_sim_base;
+    
+    if (register_index == SIMHELPER_SC_STOP         ||
+        register_index == SIMHELPER_END_WITH_RETVAL ||
+        register_index == SIMHELPER_EXCEPT_WITH_VAL ||
+        register_index == SIMHELPER_PAUSE_SIM       ||
+        register_index == SIMHELPER_SIGINT) 
+    {
+        sim_helper_address[register_index] = value;
+        return 0;
+    }
+    else if (register_index == SIMHELPER_CYCLES) 
+    {
+        *retval = sim_helper_address[register_index];
+        return 0;
+    }
+    else 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] in _sim_helper_access() : access to unmapped register\n");
+        _tty_release_lock( 0 );
+        return 1;
+    }
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/sim_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/sim_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/sim_driver.h	(revision 283)
@@ -0,0 +1,44 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : sim_driver.h
+// Date     : 23/11/2013
+// Author   : alain greiner / cesar fuguet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_SIM_DRIVERS_H_
+#define _GIET_SIM_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// SIM_HELPER registers offsets 
+///////////////////////////////////////////////////////////////////////////////////
+
+enum SoclibSimhelperRegisters
+{
+    SIMHELPER_SC_STOP,
+    SIMHELPER_END_WITH_RETVAL,
+    SIMHELPER_EXCEPT_WITH_VAL,
+    SIMHELPER_PAUSE_SIM,
+    SIMHELPER_CYCLES,
+    SIMHELPER_SIGINT,
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// SIM_HELPER access functions
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _sim_helper_access( unsigned int  register_index,
+                                        unsigned int  value,
+                                        unsigned int* retval ); 
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/spi_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/spi_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/spi_driver.c	(revision 283)
@@ -0,0 +1,209 @@
+/**
+ * \file    spi.c
+ * \date    31 August 2012
+ * \author  Cesar Fuguet <cesar.fuguet-tortolero@lip6.fr>
+ */
+#include <spi_driver.h>
+#include <utils.h>
+
+/**
+ * \param   x: input value
+ *
+ * \return  byte-swapped value
+ *
+ * \brief   byte-swap a 32bit word
+ */
+static unsigned int bswap32(unsigned int x)
+{
+  unsigned int y;
+  y =  (x & 0x000000ff) << 24;
+  y |= (x & 0x0000ff00) <<  8;
+  y |= (x & 0x00ff0000) >>  8;
+  y |= (x & 0xff000000) >> 24;
+  return y;
+}
+
+/**
+ * \param   spi :   Initialized pointer to the SPI controller
+ *
+ * \brief   Wait until the SPI controller has finished a transfer
+ *
+ * Wait until the GO_BUSY bit of the SPI controller be deasserted
+ */
+static void _spi_wait_if_busy(struct spi_dev * spi)
+{
+    register int delay;
+
+    while(SPI_IS_BUSY(spi))
+    {
+        for (delay = 0; delay < 100; delay++);
+    }
+}
+
+/**
+ * \param   spi : Initialized pointer to the SPI controller
+ *
+ * \return  void
+ *
+ * \brief   Init transfer of the tx registers to the selected slaves
+ */
+static void _spi_init_transfer(struct spi_dev * spi)
+{
+    unsigned int spi_ctrl = ioread32(&spi->ctrl);
+
+    iowrite32(&spi->ctrl, spi_ctrl | SPI_CTRL_GO_BSY);
+}
+
+/**
+ * \param   spi_freq    : Desired frequency for the generated clock from the SPI
+ *                        controller
+ * \param   sys_freq    : System clock frequency
+ *
+ * \brief   Calculated the value for the divider register in order to obtain the SPI
+ *          desired clock frequency 
+ */
+static unsigned int _spi_calc_divider_value( unsigned int spi_freq ,
+                                             unsigned int sys_freq )
+{
+    return ((sys_freq / (spi_freq * 2)) - 1);
+}
+
+void spi_put_tx(struct spi_dev * spi, unsigned char byte, int index)
+{
+    _spi_wait_if_busy(spi);
+    {
+        iowrite8(&spi->rx_tx[index % 4], byte);
+        _spi_init_transfer(spi);
+    }
+    _spi_wait_if_busy(spi);
+}
+
+volatile unsigned char spi_get_rx(struct spi_dev * spi, int index)
+{
+    return ioread8(&spi->rx_tx[index % 4]);
+}
+
+unsigned int spi_get_data( struct spi_dev * spi,
+                           paddr_t buffer      ,
+                           unsigned int count  )
+{
+    unsigned int spi_ctrl0; // ctrl value before calling this function
+    unsigned int spi_ctrl;
+    int i;
+
+    /*
+     * Only reading of one block (512 bytes) are supported
+     */
+    if ( count != 512 ) return 1;
+
+    _spi_wait_if_busy(spi);
+
+    spi_ctrl0 = ioread32(&spi->ctrl);
+
+#if 0
+    /*
+     * Read data using SPI DMA mechanism
+     * Two restrictions:
+     *   1. Can transfer only one block (512 bytes).
+     *   2. The destination buffer must be aligned to SPI burst size (64 bytes)
+     */
+    if ((buffer & 0x3f) == 0)
+    {
+        _puts("spi_get_data(): Starting DMA transfer / count = ");
+        _putx(count);
+        _puts("\n");
+
+        _puts("spi_get_data(): buffer = ");
+        _putx(buffer);
+        _puts("\n");
+
+        spi->dma_base  = (buffer      ) & ((1 << 32) - 1); // 32 lsb
+        spi->dma_baseh = (buffer >> 32) & ((1 << 8 ) - 1); // 8  msb
+        spi->dma_count = count | SPI_DMA_COUNT_READ;
+
+        while ( (spi->dma_count >> 1) );
+
+        goto reset_ctrl;
+    }
+#endif
+
+    /*
+     * Read data without SPI DMA mechanism
+     *
+     * Switch to 128 bits words
+     */
+
+    spi_ctrl = (spi_ctrl0 & ~SPI_CTRL_CHAR_LEN_MASK) | 128;
+    iowrite32(&spi->ctrl, spi_ctrl);
+
+    /* 
+     * Read data.
+     * Four 32 bits words at each iteration (128 bits = 16 bytes)
+     */
+    for (i = 0; i < count/16; i++)
+    {
+        iowrite32(&spi->rx_tx[0], 0xffffffff);
+        iowrite32(&spi->rx_tx[1], 0xffffffff);
+        iowrite32(&spi->rx_tx[2], 0xffffffff);
+        iowrite32(&spi->rx_tx[3], 0xffffffff);
+        iowrite32(&spi->ctrl,  spi_ctrl | SPI_CTRL_GO_BSY);
+
+        _spi_wait_if_busy(spi);
+
+        _physical_write( buffer, bswap32(ioread32(&spi->rx_tx[3])) ); 
+        buffer += 4;
+        _physical_write( buffer, bswap32(ioread32(&spi->rx_tx[2])) ); 
+        buffer += 4;
+        _physical_write( buffer, bswap32(ioread32(&spi->rx_tx[1])) ); 
+        buffer += 4;
+        _physical_write( buffer, bswap32(ioread32(&spi->rx_tx[0])) ); 
+        buffer += 4;
+    }
+
+//reset_ctrl:
+
+    /* Switch back to original word size */
+    iowrite32(&spi->ctrl, spi_ctrl0);
+
+    return 0;
+}
+
+void spi_ss_assert(struct spi_dev * spi, int index)
+{
+    unsigned int spi_ss = ioread32(&spi->ss);
+
+    iowrite32(&spi->ss, spi_ss | (1 << index));
+}
+
+void spi_ss_deassert(struct spi_dev * spi, int index)
+{
+    unsigned int spi_ss = ioread32(&spi->ss);
+
+    iowrite32(&spi->ss, spi_ss & ~(1 << index));
+}
+
+void _spi_init ( struct spi_dev * spi,
+                 int spi_freq        ,
+                 int sys_freq        ,
+                 int char_len        ,
+                 int tx_edge         ,
+                 int rx_edge         )
+{
+    unsigned int spi_ctrl = ioread32(&spi->ctrl);
+
+    if      ( tx_edge == 0 ) spi_ctrl |=  SPI_CTRL_TXN_EN;
+    else if ( tx_edge == 1 ) spi_ctrl &= ~SPI_CTRL_TXN_EN;
+    if      ( rx_edge == 0 ) spi_ctrl |=  SPI_CTRL_RXN_EN;
+    else if ( rx_edge == 1 ) spi_ctrl &= ~SPI_CTRL_RXN_EN;
+    if      ( char_len > 0 ) spi_ctrl  = (spi_ctrl & ~SPI_CTRL_CHAR_LEN_MASK) |
+                                         (char_len &  SPI_CTRL_CHAR_LEN_MASK);
+
+    iowrite32(&spi->ctrl, spi_ctrl);
+
+    if (spi_freq > 0 && sys_freq > 0)
+        iowrite32(&spi->divider, _spi_calc_divider_value(spi_freq, sys_freq));
+}
+
+/*
+ * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4
+ */
Index: /branch/giet_vm_ioc_drivers/giet_drivers/spi_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/spi_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/spi_driver.h	(revision 283)
@@ -0,0 +1,155 @@
+/**
+ * \file  : spi_driver.h
+ * \date  : 30 August 2012
+ * \author: Cesar Fuguet <cesar.fuguet-tortolero@lip6.fr>
+ *
+ * This file contains the definition of a driver for the SPI controller
+ */
+
+#ifndef SPI_DRIVER_H
+#define SPI_DRIVER_H
+
+#include <io.h>
+#include <mapping_info.h>
+
+/**
+ * SPI type definition
+ */
+struct spi_dev
+{
+    /**
+     * RX/TX registers of the SPI controller 
+     */
+    unsigned int rx_tx[4];
+
+    /**
+     * Control register of the SPI controller
+     */
+    unsigned int ctrl;
+
+    /**
+     * Divider register for the SPI controller generated clock signal
+     */
+    unsigned int divider;
+
+    /**
+     * Slave select register of the SPI controller
+     */
+    unsigned int ss;
+    unsigned int dma_base;
+    unsigned int dma_baseh;
+    unsigned int dma_count;
+};
+
+/**
+ * \param   spi     : initialized pointer to a SPI controller.
+ * \param   byte    : Byte to send to the SPI controller
+ * \param   index   : index of the TX register in the SPI (TX[index])
+ *
+ * \return  void
+ *
+ * \brief   Send a byte to one of the tx buffer registers of the
+ *          SPI controller
+ */
+void spi_put_tx(struct spi_dev * spi, unsigned char byte, int index);
+
+/**
+ * \param   spi     : initialized pointer to a SPI controller.
+ * \param   index   : index of the RX register in the SPI (RX[index])
+ *
+ * \return  byte from the RX[index] register
+ *
+ * \brief   Get a byte from one of the rx buffer registers of the
+ *          SPI controller
+ */
+inline volatile unsigned char spi_get_rx(struct spi_dev * spi, int index);
+
+/**
+ * \param   spi     : initialized pointer to a SPI controller.
+ * \param   buf     : buffer to store data read
+ * \param   count   : byte count to read
+ *
+ * \return  void
+ *
+ * \brief   get a data block from the SPI controller using 128bits
+ *          reads if possible
+ */
+unsigned int spi_get_data(struct spi_dev * spi, paddr_t buffer, unsigned int count);
+
+/**
+ * \param   spi     : initialized pointer to a SPI controller.
+ * \param   index   : index of the slave select signal to assert
+ *
+ * \return  void
+ *
+ * \brief   Set the index selected slave select signal (ss[index] <= '0')
+ */
+inline void spi_ss_assert(struct spi_dev * spi, int index);
+
+/**
+ * \param   spi     : initialized pointer to a SPI controller.
+ * \param   index   : index of the slave select signal to deassert
+ *
+ * \return  void
+ *
+ * \brief   Unset the index selected slave select signal (ss[index] <= '0')
+ */
+inline void spi_ss_deassert(struct spi_dev * spi, int index);
+
+/**
+ * \param   spi         : initialized pointer to a SPI controller.
+ * \param   spi_freq    : SPI Master to Slave clock frequency (in Hz)
+ * \param   sys_freq    : System clock frequency (in Hz)
+ * \param   char_len    : number to bits to transmit in one transfer
+ * \param   tx_edge     : when 0, the Master Out Slave In signal is changed
+ *                        on the falling edge of the clock
+ * \param   rx_edge     : when 0, the Master In Slave Out signal is latched
+ *                        on the falling edge of the clock
+ *
+ * \return  void
+ *
+ * \brief   Configure the SPI controller
+ * \note    Any of the arguments can be less than 0 if you want to keep the old value
+ */
+void _spi_init (
+        struct spi_dev * spi,
+        int spi_freq        ,
+        int sys_freq        ,
+        int char_len        ,
+        int tx_edge         ,
+        int rx_edge         );
+
+/**
+ * SPI macros and constants
+ */
+#define SPI_TX_POSEDGE         1           /**< MOSI is changed on neg edge   */
+#define SPI_TX_NEGEDGE         0           /**< MOSI is changed on pos edge   */
+#define SPI_RX_POSEDGE         1           /**< MISO is latched on pos edge   */
+#define SPI_RX_NEGEDGE         0           /**< MISO is latched on neg edge   */
+
+#define SPI_CTRL_ASS_EN        ( 1 << 13 ) /**< Auto Slave Sel Assertion      */
+#define SPI_CTRL_IE_EN         ( 1 << 12 ) /**< Interrupt Enable              */
+#define SPI_CTRL_LSB_EN        ( 1 << 11 ) /**< LSB are sent first            */
+#define SPI_CTRL_TXN_EN        ( 1 << 10 ) /**< MOSI is changed on neg edge   */
+#define SPI_CTRL_RXN_EN        ( 1 << 9  ) /**< MISO is latched on neg edge   */
+#define SPI_CTRL_GO_BSY        ( 1 << 8  ) /**< Start the transfer            */
+#define SPI_CTRL_DMA_BSY        (1 << 16)  /***   DMA in progress             */
+#define SPI_CTRL_CHAR_LEN_MASK (  0xFF   ) /**< Bits transmited in 1 transfer */
+#define SPI_RXTX_MASK          (  0xFF   ) /**< Mask for the an RX/TX value   */
+
+#define SPI_DMA_COUNT_READ      (1 << 0) /* operation is a read (else write) */
+
+/** 
+ * \param  x : Initialized pointer to the SPI controller
+ *
+ * \return 1 if there is an unfinished transfer in the SPI controller
+ *
+ * \brief  Check the GO_BUSY bit of the SPI Controller
+ */
+#define SPI_IS_BUSY(x)         ((ioread32(&x->ctrl) & (SPI_CTRL_GO_BSY|SPI_CTRL_DMA_BSY)) != 0) ? 1 : 0
+
+#endif
+
+/*
+ * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4
+ */
Index: /branch/giet_vm_ioc_drivers/giet_drivers/tim_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/tim_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/tim_driver.c	(revision 283)
@@ -0,0 +1,185 @@
+//////////////////////////////////////////////////////////////////////////////////////
+// File     : timer_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+//////////////////////////////////////////////////////////////////////////////////////
+// The timer_driver.c and timer_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the SoCLib vci_multi_timer component.
+//
+// It can exist several multi_timers in the architecture (at most one per cluster),
+// and each one can contain several timers (called channels).
+//
+// There is two types of timers: 
+// - "system" timers : one per processor, used for context switch.
+//   local_id in [0, NB_PROCS_MAX-1],
+// - "user" timers : requested by the task in the mapping_info data structure.
+//   For each user timer, the timer_id is stored in the context of the task.
+// The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id
+//
+// The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in the
+// hard_config.h file.
+//
+// The register offsets must be defined in the hwr_mapping.h file.
+/////////////////////////////////////////////////////////////////////////////////////
+// The virtual base address of the segment associated to a channel is:
+//
+//     seg_tim_base + cluster_xy * vseg_cluster_increment + TIMER_SPAN * timer_id
+//
+// The seg_tim_base and vseg_cluster_increment values must be defined 
+// in the giet_vsegs.ld file.
+/////////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <tim_driver.h>
+#include <utils.h>
+
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(NB_PROCS_MAX) 
+# error: You must define NB_PROCS_MAX in the hard_config.h file
+#endif
+
+#if !defined(NB_TIM_CHANNELS)
+#define NB_TIM_CHANNELS 0
+#endif
+
+#if ( (NB_TIM_CHANNELS + NB_PROC_MAX) > 32 )
+# error: NB_TIM_CHANNELS + NB_PROCS_MAX cannot be larger than 32
+#endif
+
+///////////////////  Timer global variables ////////////////////////////////////////
+
+#define in_unckdata __attribute__((section (".unckdata")))
+
+#if (NB_TIM_CHANNELS > 0)
+in_unckdata volatile unsigned char _user_timer_event[X_SIZE*Y_SIZE*NB_TIM_CHANNELS] 
+                            = { [0 ... ((X_SIZE*Y_SIZE*NB_TIM_CHANNELS) - 1)] = 0 };
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////
+//     _timer_start()
+// This function activates a timer in the vci_timer component
+// by writing in the proper register the period value.
+// It can be used by both the kernel to initialise a "system" timer,
+// or by a task (through a system call) to configure an "user" timer.
+// Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _timer_start( unsigned int cluster_xy, 
+                           unsigned int local_id, 
+                           unsigned int period) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                  return 1; 
+    if (y >= Y_SIZE)                  return 1; 
+    if (local_id >= NB_TIM_CHANNELS)  return 1;
+
+    unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 
+                                  (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
+    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3;
+    return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//     _timer_stop()
+// This function desactivates a timer in the vci_timer component
+// by writing in the proper register.
+// Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _timer_stop( unsigned int cluster_xy, 
+                          unsigned int local_id) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                  return 1; 
+    if (y >= Y_SIZE)                  return 1; 
+    if (local_id >= NB_TIM_CHANNELS)  return 1;
+
+    unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 
+                                  (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0;
+    return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//     _timer_reset_irq()
+// This function acknowlegge a timer interrupt in the vci_timer  
+// component by writing in the proper register.
+// It can be used by both the isr_switch() for a "system" timer, 
+// or by the _isr_timer() for an "user" timer.
+// Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _timer_reset_irq( unsigned int cluster_xy, 
+                               unsigned int local_id ) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                  return 1; 
+    if (y >= Y_SIZE)                  return 1; 
+    if (local_id >= NB_TIM_CHANNELS)  return 1;
+
+    unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 
+                                   (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0;
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//     _timer_reset_cpt()
+// This function resets the timer counter. To do so, we re-write the period
+// in the proper register, what causes the count to restart.
+// The period value is read from the same (TIMER_PERIOD) register,
+// this is why in appearance we do nothing useful (read a value
+// from a register and write this value in the same register)
+// This function is called during a context switch (user or preemptive)
+//////////////////////////////////////////////////////////////////////i//////
+unsigned int _timer_reset_cpt( unsigned int cluster_xy, 
+                               unsigned int local_id) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                  return 1; 
+    if (y >= Y_SIZE)                  return 1; 
+    if (local_id >= NB_TIM_CHANNELS)  return 1;
+
+    // We suppose that the TIMER_MODE register value is 0x3
+    unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 
+                                   (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD];
+    timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period;
+    return 0;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/tim_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/tim_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/tim_driver.h	(revision 283)
@@ -0,0 +1,55 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : tim_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner 
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_TIM_DRIVERS_H_
+#define _GIET_TIM_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// TIMER (vci_multi_timer) registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum TIMER_registers 
+{
+    TIMER_VALUE     = 0,
+    TIMER_MODE      = 1,
+    TIMER_PERIOD    = 2,
+    TIMER_RESETIRQ  = 3,
+    /**/
+    TIMER_SPAN      = 4,
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// Timer access functions and global variables
+///////////////////////////////////////////////////////////////////////////////////
+
+extern volatile unsigned char _timer_event[];
+
+extern unsigned int _timer_start( unsigned int cluster_xy, 
+                                  unsigned int local_id, 
+                                  unsigned int period );
+
+extern unsigned int _timer_stop( unsigned int cluster_xy,
+                                 unsigned int local_id );
+
+extern unsigned int _timer_reset_irq( unsigned int cluster_xy, 
+                                      unsigned int local_id );
+
+extern unsigned int _timer_reset_cpt( unsigned int cluster_xy, 
+                                      unsigned int local_id);
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/tty_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/tty_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/tty_driver.c	(revision 283)
@@ -0,0 +1,227 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : tty_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The tty_driver.c and tty_drivers.h files are part ot the GIET-VM kernel.
+// This driver supports the SocLib vci_multi_tty component.
+//
+// It can exist only one multi_tty controler in the architecture.
+//
+// The total number of TTY terminals must be defined by the configuration 
+// parameter NB_TTY_CHANNELS in the hard_config.h file.
+//
+// The register offsets must be defined in the hwr_mapping.h file.
+//
+// The "system" terminal is TTY[0].
+// The "user" TTYs are allocated to applications by the GIET in the boot phase,
+// as defined in the mapping_info data structure. The corresponding tty_id must 
+// be stored in the context of the task by the boot code.
+///////////////////////////////////////////////////////////////////////////////////
+// The virtual base address of the segment associated to a channel is: 
+//
+//                  seg_tty_base  + TTY_SPAN * channel_id
+//
+// The seg_tty_base virtual base addresses must be defined in giet_vsegs.ld file.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <tty_driver.h>
+#include <ctx_handler.h>
+#include <utils.h>
+
+#if !defined(NB_TTY_CHANNELS)
+# error: You must define NB_TTY_CHANNELS in the hard_config.h file
+#endif
+
+#if (NB_TTY_CHANNELS < 1)
+# error: NB_TTY_CHANNELS cannot be smaller than 1!
+#endif
+
+#define in_unckdata __attribute__((section (".unckdata")))
+
+/////////////////   TTY global variables
+in_unckdata volatile unsigned char _tty_get_buf[NB_TTY_CHANNELS];
+in_unckdata volatile unsigned char _tty_get_full[NB_TTY_CHANNELS] 
+                                     = { [0 ... NB_TTY_CHANNELS - 1] = 0 };
+
+/////////////////////////////////////////////////////////////////////////////////
+// This non-blocking function writes a character string from a fixed-length 
+// buffer to the TTY_WRITE register of a TTY terminal identified by the
+// channel argument. If the channel argument is 0xFFFFFFFF, the channel 
+// index is obtained from the current taxk context. 
+// It doesn't use any interrupt.
+// This is a non blocking call: it tests the TTY_STATUS register, and stops
+// the transfer as soon as the TTY_STATUS[WRITE] bit is set. 
+/////////////////////////////////////////////////////////////////////////////////
+// Returns  the number of characters that have been written.
+/////////////////////////////////////////////////////////////////////////////////
+unsigned int _tty_write( const char*  buffer,    
+                         unsigned int length,    // number of characters
+                         unsigned int channel)   // channel index 
+{
+    unsigned int nwritten;
+    unsigned int tty_id;
+    unsigned int* tty_address = (unsigned int *) &seg_tty_base;
+
+    // compute tty channel
+    if( channel == 0xFFFFFFFF )
+    {
+        tty_id = _get_context_slot(CTX_TTY_ID);
+    }
+    else
+    {
+        tty_id = (unsigned int)channel;
+    }
+
+    // write string to TTY channel
+    for (nwritten = 0; nwritten < length; nwritten++) 
+    {
+        // check tty's status 
+        if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) break;
+        _tty_write_data( tty_id, buffer[nwritten] );
+    }
+    return nwritten;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This non-blocking function fetches one character from the 
+// terminal identified by the channel argument. If the channel argument 
+// is 0xFFFFFFFF, the channel index is obtained from the current task context. 
+// It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been
+// filled by the TTY_ISR.
+// It test the _tty_get_full[tty_id] register, read the _tty_get_buf[tty_id] 
+// buffer, writes this character to the target buffer, and resets the
+// _tty_get_full[tty_id] register.
+// The length argument is not used.
+//////////////////////////////////////////////////////////////////////////////
+// Returns  the number of characters that have been read (0/1).
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _tty_read( char*        buffer, 
+                        unsigned int length,    // unused
+                        unsigned int channel)   // channel index
+{
+    
+    unsigned int tty_id;
+
+    // compute tty channel
+    if( channel == 0xFFFFFFFF )
+    {
+        tty_id = _get_context_slot(CTX_TTY_ID);
+    }
+    else
+    {
+        tty_id = (unsigned int)channel;
+    }
+
+    // read one character from TTY channel
+    if (_tty_get_full[tty_id] == 0) 
+    {
+        return 0;
+    }
+    else 
+    {
+        *buffer = _tty_get_buf[tty_id];
+        _tty_get_full[tty_id] = 0;
+        return 1;
+    }
+}
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+// This function try to take the hardwired lock protecting exclusive access 
+// to TTY terminal identified by the channel argument.
+// It returns only when the lock has been successfully taken.
+//////////////////////////////////////////////////////////////////////////////
+void _tty_get_lock( unsigned int channel )
+{
+    unsigned int* tty_address = (unsigned int *) &seg_tty_base;
+
+    if( channel >= NB_TTY_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _tty_get_lock() : illegal TTY index\n");
+        _exit();        
+    }
+
+    while ( tty_address[channel * TTY_SPAN + TTY_CONFIG] );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This function releases the hardwired lock protecting exclusive access 
+// to TTY terminal identified by the channel argument.
+//////////////////////////////////////////////////////////////////////////////
+void _tty_release_lock( unsigned int channel )
+{
+    unsigned int* tty_address = (unsigned int *) &seg_tty_base;
+
+    if( channel >= NB_TTY_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _tty_release_lock() : illegal TTY index\n");
+        _exit();        
+    }
+
+    tty_address[channel * TTY_SPAN + TTY_CONFIG] = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This function returns the content of the TTY_READ register in the 
+// TTY terminal identified by the channel argument.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _tty_read_data( unsigned int channel )
+{
+    unsigned int* tty_address = (unsigned int *) &seg_tty_base;
+
+    if( channel >= NB_TTY_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _tty_read_data() : illegal TTY index\n");
+        _exit();        
+    }
+
+    return tty_address[channel * TTY_SPAN + TTY_READ];
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This function returns the content of the TTY_STATUS register in the 
+// TTY terminal identified by the channel argument.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _tty_get_status( unsigned int channel )
+{
+    unsigned int* tty_address = (unsigned int *) &seg_tty_base;
+
+    if( channel >= NB_TTY_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _tty_get_status() : illegal TTY index\n");
+        _exit();        
+    }
+
+    return tty_address[channel * TTY_SPAN + TTY_STATUS];
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// This function writes one character in the TTY_WRITE register in the 
+// TTY terminal identified by the channel argument.
+//////////////////////////////////////////////////////////////////////////////
+void _tty_write_data( unsigned int channel,
+                      char         byte )
+{
+    unsigned int* tty_address = (unsigned int *) &seg_tty_base;
+
+    if( channel >= NB_TTY_CHANNELS )
+    {
+        _puts("[GIET ERROR] in _tty_write_data() : illegal TTY index\n");
+        _exit();        
+    }
+
+    tty_address[channel * TTY_SPAN + TTY_WRITE] = (unsigned int) byte;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/tty_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/tty_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/tty_driver.h	(revision 283)
@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : tty_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_TTY_DRIVERS_H_
+#define _GIET_TTY_DRIVERS_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// TTY (vci_multi_tty) registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum TTY_registers 
+{
+    TTY_WRITE   = 0,
+    TTY_STATUS  = 1,
+    TTY_READ    = 2,
+    TTY_CONFIG  = 3,
+    /**/
+    TTY_SPAN    = 4,
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// TTY access functions and variables
+///////////////////////////////////////////////////////////////////////////////////
+
+extern volatile unsigned char _tty_get_buf[];
+
+extern volatile unsigned char _tty_get_full[];
+
+/////// rather high level access functions ///////////////////////////////////////
+
+extern unsigned int _tty_write( const char*  buffer,
+                                unsigned int length,     // number of characters 
+                                unsigned int channel );  // channel index
+
+extern unsigned int _tty_read(  char*        buffer,
+                                unsigned int length,     // unused
+                                unsigned int channel );  // channel index
+
+/////// very low level access functions //////////////////////////////////////////
+
+extern void _tty_write_data( unsigned int channel, char byte );
+
+extern unsigned int _tty_read_data( unsigned int channel );
+
+extern unsigned int _tty_get_status( unsigned int channel );
+
+extern void _tty_get_lock( unsigned int channel );
+
+extern void _tty_release_lock( unsigned int channel );
+
+///////////////////////////////////////////////////////////////////////////////////
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/xcu_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/xcu_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/xcu_driver.c	(revision 283)
@@ -0,0 +1,313 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : xcu_driver.c
+// Date     : 23/05/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel.
+// This driver supports the SoCLib vci_xicu, that is a vectorised interrupt
+// controler supporting IPI (Inter Processor Interrupts) and integrated timers.
+//
+// It can exist several interrupt controller unit in the architecture 
+// (one per cluster), and each one can contain several channels.
+// The number of XICU channels is equal to NB_PROCS_MAX, because there is 
+// one private XICU channel per processor in a cluster.
+////////////////////////////////////////////////////////////////////////////////
+// The virtual base address of the segment associated to the component is:
+//
+//      seg_xcu_base + cluster_xy * vseg_cluster_increment
+//
+// The seg_xcu_base and vseg_cluster_increment values must be defined 
+// in giet_vsegs.ld file.
+////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <xcu_driver.h>
+#include <tty_driver.h>
+#include <mapping_info.h>
+#include <utils.h>
+
+#if !defined(X_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(Y_SIZE) 
+# error: You must define X_SIZE in the hard_config.h file
+#endif
+
+#if !defined(X_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(Y_WIDTH) 
+# error: You must define X_WIDTH in the hard_config.h file
+#endif
+
+#if !defined(NB_PROCS_MAX) 
+# error: You must define NB_PROCS_MAX in the hard_config.h file
+#endif
+
+#if !defined( USE_XICU )
+# error: You must define USE_XICU in the hard_config.h file
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+//     _xcu_set_mask()
+// This function set the mask register for the XICU channel identified by the
+// cluster index and the processor index multiplied by the number of IRQ per
+// processor.
+// All '1' bits are set / all '0' bits are not modified.
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _xcu_set_mask( unsigned int cluster_xy, 
+                            unsigned int irq_index,
+                            unsigned int value,
+                            unsigned int irq_type ) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                                     return 1; 
+    if (y >= Y_SIZE)                                     return 1; 
+    if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1; 
+
+#if USE_XICU
+    volatile unsigned int* xcu_address =
+        (unsigned int *) ((unsigned int)&seg_xcu_base + 
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    unsigned int func;
+    if      (irq_type == IRQ_TYPE_PTI) func = XICU_MSK_PTI_ENABLE;
+    else if (irq_type == IRQ_TYPE_SWI) func = XICU_MSK_WTI_ENABLE;
+    else                               func = XICU_MSK_HWI_ENABLE;
+    xcu_address[XICU_REG(func,irq_index)] = value;
+    return 0;
+#else
+    _tty_get_lock( 0 );
+    _puts("[GIET ERROR] _xcu_set_mask should not be used if USE_XICU is not set\n");
+    _tty_release_lock( 0 );
+    return 1;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//     _xcu_get_index()
+// This function returns the index of the highest priority (smaller index) 
+// - active HWI (Hardware Interrupt), or
+// - active PTI (Timer Interrupt), or
+// - active SWI (Software Interrupt).
+// The ICU channel is identified by the cluster index and the processor index
+// multiplied by the number of IRQ per processor.
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _xcu_get_index( unsigned int cluster_xy, 
+                             unsigned int irq_index, 
+                             unsigned int * buffer) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)                                     return 1; 
+    if (y >= Y_SIZE)                                     return 1; 
+    if (irq_index >= (NB_PROCS_MAX * IRQ_PER_PROCESSOR)) return 1; 
+
+#if USE_XICU
+    volatile unsigned int* xcu_address =
+        (unsigned int *) ((unsigned int)&seg_xcu_base + 
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    unsigned int prio = xcu_address[XICU_REG(XICU_PRIO,irq_index)];
+    unsigned int pti_ok = (prio & 0x00000001);
+    unsigned int hwi_ok = (prio & 0x00000002);
+    unsigned int swi_ok = (prio & 0x00000004);
+    unsigned int pti_id = (prio & 0x00001F00) >> 8;
+    unsigned int hwi_id = (prio & 0x001F0000) >> 16;
+    unsigned int swi_id = (prio & 0x1F000000) >> 24;
+    if      (pti_ok)  *buffer = pti_id;
+    else if (hwi_ok)  *buffer = hwi_id;
+    else if (swi_ok)  *buffer = swi_id; 
+    else              *buffer = 32; 
+    return 0;
+#else
+    _tty_get_lock( 0 );
+    _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XICU is not set\n");
+    _tty_release_lock( 0 );
+    return 1;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//     _xcu_send_ipi()
+// This function can be used only in an architecture using  XICU components.
+// It writes the "wdata" value in the mailbox defined by the cluster index
+// and the processor index.
+// Giet-VM supports at most NB_PROCS_MAX mailboxes:
+// (0 <= wti_index <= NB_PROCS_MAX-1)
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _xcu_send_ipi( unsigned int cluster_xy,
+                            unsigned int wti_index,
+                            unsigned int wdata )
+{ 
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)               return 1; 
+    if (y >= Y_SIZE)               return 1; 
+    if (wti_index >= NB_PROCS_MAX) return 1; 
+
+#if USE_XICU
+    volatile unsigned int* xcu_address =
+        (unsigned int *) ((unsigned int)&seg_xcu_base + 
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    xcu_address[XICU_REG(XICU_WTI_REG,wti_index)] = wdata;
+    return 0; 
+#else
+    _tty_get_lock( 0 );
+    _puts("[GIET ERROR] _xcu_send_ipi should not be used if USE_XICU is not set\n");
+    _tty_release_lock( 0 );
+    return 1;
+#endif
+} 
+
+////////////////////////////////////////////////////////////////////////////////
+//    _xcu_timer_start()
+// This function activates a timer contained in XICU by writing in the
+// proper register the period value.
+// Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////
+unsigned int _xcu_timer_start( unsigned int cluster_xy,
+                               unsigned int pti_index,
+                               unsigned int period )
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+
+#if USE_XICU
+    volatile unsigned int* xcu_address =
+        (unsigned int *) ((unsigned int)&seg_xcu_base + 
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period;
+    return 0;
+#else
+    _tty_get_lock( 0 );
+    _puts("[GIET ERROR] _xcu_timer_start should not be used if USE_XICU is not set\n");
+    _tty_release_lock( 0 );
+    return 1;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//     _xcu_timer_stop()
+// This function desactivates a timer in XICU component
+// by writing in the proper register.
+// Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _xcu_timer_stop( unsigned int cluster_xy, 
+                              unsigned int pti_index) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+
+#if USE_XICU
+    volatile unsigned int * xcu_address =
+        (unsigned int *) ((unsigned int)&seg_xcu_base + 
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0;
+    return 0;
+#else
+    _tty_get_lock( 0 );
+    _puts("[GIET ERROR] _xcu_timer_stop should not be used if USE_XICU is not set\n");
+    _tty_release_lock( 0 );
+    return 1;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//     _xcu_timer_reset_irq()
+// This function acknowlegge a timer interrupt in XICU 
+// component by reading in the proper register.
+// It can be used by both the isr_switch() for a "system" timer, 
+// or by the _isr_timer() for an "user" timer.
+// Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 
+                                   unsigned int pti_index ) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+
+#if USE_XICU
+    volatile unsigned int * xcu_address =
+        (unsigned int *) ((unsigned int)&seg_xcu_base +
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    xcu_address[XICU_REG(XICU_PTI_ACK, pti_index)];
+    return 0;
+#else
+    _tty_get_lock( 0 );
+    _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n");
+    _tty_release_lock( 0 );
+    return 1;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//     _xcu_timer_reset_cpt()
+// This function resets a timer counter. To do so, we re-write the period
+// in the proper register, what causes the count to restart.
+// The period value is read from the same (TIMER_PERIOD) register,
+// this is why in appearance we do nothing useful (read a value
+// from a register and write this value in the same register)
+// This function is called during a context switch (user or preemptive)
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy, 
+                                   unsigned int pti_index ) 
+{
+    // parameters checking 
+    unsigned int x = cluster_xy >> Y_WIDTH;
+    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
+    if (x >= X_SIZE)             return 1; 
+    if (y >= Y_SIZE)             return 1; 
+
+#if USE_XICU
+    volatile unsigned int * xcu_address =
+        (unsigned int *) ((unsigned int) &seg_xcu_base + 
+        (cluster_xy * (unsigned int)&vseg_cluster_increment));
+
+    unsigned int period = xcu_address[XICU_REG(XICU_PTI_PER, pti_index)];
+
+    // we write 0 first because if the timer is currently running, 
+    // the corresponding timer counter is not reset
+    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = 0;
+    xcu_address[XICU_REG(XICU_PTI_PER, pti_index)] = period;
+    return 0;
+#else
+    _tty_get_lock( 0 );
+    _puts("[GIET ERROR] _xcu_timer_reset_irq should not be used if USE_XICU is not set\n");
+    _tty_release_lock( 0 );
+    return 1;
+#endif
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_drivers/xcu_driver.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_drivers/xcu_driver.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_drivers/xcu_driver.h	(revision 283)
@@ -0,0 +1,83 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : xcu_driver.h
+// Date     : 01/11/2013
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_XCU_DRIVER_H_
+#define _GIET_XCU_DRIVER_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+// XICU registers offsets
+///////////////////////////////////////////////////////////////////////////////////
+
+enum Xicu_registers 
+{
+    XICU_WTI_REG = 0,
+    XICU_PTI_PER = 1,
+    XICU_PTI_VAL = 2,
+    XICU_PTI_ACK = 3,
+
+    XICU_MSK_PTI = 4,
+    XICU_MSK_PTI_ENABLE = 5,
+    XICU_MSK_PTI_DISABLE = 6,
+    XICU_PTI_ACTIVE = 6,
+
+    XICU_MSK_HWI = 8,
+    XICU_MSK_HWI_ENABLE = 9,
+    XICU_MSK_HWI_DISABLE = 10,
+    XICU_HWI_ACTIVE = 10,
+
+    XICU_MSK_WTI = 12,
+    XICU_MSK_WTI_ENABLE = 13,
+    XICU_MSK_WTI_DISABLE = 14,
+    XICU_WTI_ACTIVE = 14,
+
+    XICU_PRIO = 15,
+};
+
+#define XICU_REG(func, index) (((func)<<5)|(index))
+ 
+///////////////////////////////////////////////////////////////////////////////////
+// XICU access functions 
+///////////////////////////////////////////////////////////////////////////////////
+
+extern unsigned int _xcu_get_index( unsigned int cluster_xy, 
+                                    unsigned int irq_index, 
+                                    unsigned int * buffer );
+
+extern unsigned int _xcu_set_mask( unsigned int cluster_xy,
+                                   unsigned int irq_index,
+                                   unsigned int mask, 
+                                   unsigned int is_timer );
+
+extern unsigned int _xcu_send_ipi( unsigned int cluster_xy,
+                                   unsigned int wti_index,
+                                   unsigned int wdata );
+
+extern unsigned int _xcu_timer_start( unsigned int cluster_xy, 
+                                      unsigned int pti_index,
+                                      unsigned int period ); 
+
+extern unsigned int _xcu_timer_stop( unsigned int cluster_xy, 
+                                     unsigned int pti_index ); 
+
+extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 
+                                          unsigned int pti_index );
+
+extern unsigned int _xcu_timer_reset_cpt( unsigned int cluster_xy, 
+                                          unsigned int pti_index ); 
+
+///////////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_fat32/fat32.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_fat32/fat32.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_fat32/fat32.c	(revision 283)
@@ -0,0 +1,1442 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : fat32.c 
+// Date     : 01/09/2013
+// Authors  : Marco Jankovic, Cesar Fuguet & Alain Greiner
+// Copyright (c) UPMC-LIP6
+//////////////////////////////////////////////////////////////////////////////////
+// The fat32.h and fat32.c files define a library of access functions
+// to a FAT32 partition on a block device. It is intended to be used
+// by the GIET_VM nano-kernel for both the boot code and the kernel code.
+// This code uses functions defined in the utils.c and drivers.c files.
+//////////////////////////////////////////////////////////////////////////////////
+// Implementation notes:
+// 1. the "lba" (Logical Block Address) is the physical sector index on
+//    the block device. The physical sector size is supposed to be 512 bytes.
+// 2. the "cluster" variable is actually a cluster index. A cluster contains
+//    typically 8 sectors (4K bytes) and the cluster index is a 32 bits word.
+// 2. This FAT32 library uses a FAT cache whose storage capacity is one
+//    sector (512 bytes, or 128 cluster indexes in FAT)
+// 3. This FAT32 library can be used in three modes: BOOT/KERNEL/USER
+//    defining three different behaviours for the IOC driver.
+//////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <fat32.h>
+#include <tty_driver.h>
+#include <ioc_driver.h>
+#include <utils.h>
+
+//////////////////////////////////////////////////////////////////////////////////
+//      Global variable used by all FAT access functions
+//////////////////////////////////////////////////////////////////////////////////
+
+__attribute__((section (".kdata"))) 
+fat32_fs_t fat __attribute__((aligned(64)));
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function displays the content of the FAT cache
+//////////////////////////////////////////////////////////////////////////////////
+#if GIET_DEBUG_FAT
+void display_fat_cache()
+{
+    unsigned int line;
+    unsigned int word;
+    unsigned int temp[9];
+
+    temp[8] = 0;
+
+    _tty_get_lock( 0 );
+    _puts("\n*********************** fat_cache_lba = ");
+    _putx( fat.cache_lba );
+    _puts(" **************************\n");
+
+    for ( line=0 ; line<16 ; line++ )
+    {
+        // display address 
+        _putx( (fat.cache_lba<<9) + (line<<5) );
+        _puts(" : ");
+
+        // display data hexa
+        for ( word=0 ; word<8 ; word++ )
+        {
+            unsigned int byte  = (line<<5) + (word<<2);
+            unsigned int hexa  = (fat.fat_cache[byte  ]<<24) |
+                                 (fat.fat_cache[byte+1]<<16) |
+                                 (fat.fat_cache[byte+2]<< 8) |
+                                 (fat.fat_cache[byte+3]);
+            _putx( hexa );
+            _puts(" | ");
+
+            // prepare display ascii
+            temp[word] = fat.fat_cache[byte]         |
+                         (fat.fat_cache[byte+1]<<8)  |
+                         (fat.fat_cache[byte+2]<<16) |
+                         (fat.fat_cache[byte+3]<<24) ;
+        }
+        
+        // display data ascii 
+        _puts( (char*)temp );
+        _puts("\n");
+    }
+    _puts("***************************************************************************\n");
+    _tty_release_lock( 0 );
+} // end display_fat_cache()  
+#endif
+ 
+//////////////////////////////////////////////////////////////////////////////////
+// This function returns the length of a FAT field. This field is identified
+// man by an (offset,length) mnemonic defined in fat32.h file.
+//////////////////////////////////////////////////////////////////////////////////
+static inline int get_length( int offset, 
+                              int length)
+{
+    return length;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Read one 32 bits word in a char[] buffer, taking endianness into account. 
+// This field is defined by the offset and size arguments.
+//////////////////////////////////////////////////////////////////////////////
+static unsigned int read_entry( unsigned int   offset,
+                                unsigned int   size,
+                                char*          buffer,
+                                unsigned int   little_indian )
+{
+    unsigned int turn;
+    unsigned int res  = 0;
+    unsigned int mask = 0x000000ff;
+
+    if( little_indian )
+    {
+        turn = size;
+        while( turn != 1 )
+        {
+            res = res | (buffer[offset + (turn-1)] & mask);
+            res = res << 8;
+            turn--;
+        }
+        res = (buffer[offset + (turn-1)] & mask) | res;
+    }
+    else
+    {
+        turn = 0;
+        while( turn != size - 1 )
+        {
+
+            res = res  | (buffer[ offset + turn ] & mask );
+            res = res << 8;
+            turn++;
+        }
+        res = res | (buffer[offset + turn] & mask);
+    }
+    return res;
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function retuns the cluster index from the lba of a DATA sector.
+// The lba must be larger than the lba of the first DATA sector.
+// The DATA region indexing starts a cluster 2.
+//////////////////////////////////////////////////////////////////////////////////
+static inline unsigned int lba_to_cluster( unsigned int lba )                   
+{
+   if (lba < fat.data_lba ) return 0;
+
+   return ( (lba - fat.data_lba) / fat.sectors_per_cluster) + 2; 
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// This function retuns the lba of first sector in DATA region 
+// from the cluster index. The cluster index must be larger than 2. 
+//////////////////////////////////////////////////////////////////////////////////
+static inline unsigned int cluster_to_lba( unsigned int cluster )       
+{
+   if ( cluster < 2 ) return 0; 
+
+   return  (fat.sectors_per_cluster * (cluster - 2)) + fat.data_lba;
+}
+
+///////////////////////////////////////////////////////////////////////////////// 
+// This function search the FAT (using the FAT cache), and returns 
+// the next cluster index from the curent cluster index in the FAT.
+// remark: a sector of FAT contains 128 cluster indexes.
+/////////////////////////////////////////////////////////////////////////////////
+static unsigned int get_next_cluster_id( unsigned int mode,
+                                         unsigned int cluster )
+{
+    // compute lba of the sector containing the cluster index
+    unsigned int lba = fat.partition_lba + 32 + (cluster / 128);
+
+    if ( lba == fat.cache_lba )      // hit in cache
+    {
+        return read_entry( ((cluster % 128) * 4), 
+                           4, 
+                           fat.fat_cache,
+                           1 );
+    }
+    else                                  // miss in cache
+    {
+        // we cannot access fat in user mode
+        if( mode == IOC_USER_MODE ) mode = IOC_KERNEL_MODE;
+        
+        // access fat
+        if( _ioc_read( mode,              // mode for IOC driver
+                       lba,               // sector index 
+                       fat.fat_cache,     // fat cache
+                       1 ) )              // one sector
+        {
+            _tty_get_lock( 0 );
+            _puts("[FAT_ERROR] in get_next cluster_id() cannot read block ");
+            _putd( lba );
+            _puts("\n");
+            _tty_release_lock( 0 );
+            return 1;
+        }
+        fat.cache_lba = lba;
+
+        return read_entry( ((cluster % 128) * 4), 
+                           4, 
+                           fat.fat_cache,
+                           1 );
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This function returns the cluster index from a (32 bytes) directory entry
+///////////////////////////////////////////////////////////////////////////////
+static inline unsigned int read_cluster( char* buf )                 
+{
+   unsigned int cluster = read_entry( DIR_FST_CLUS_HI, buf, 1 ) << 16;
+   cluster = cluster | read_entry( DIR_FST_CLUS_LO, buf, 1 );
+   return cluster;
+} 
+
+//////////////////////////////////////////////////////
+static inline unsigned char to_upper(unsigned char c)
+{
+   if (c >= 'a' && c <= 'z') return (c & ~(0x20));
+   else                      return c;
+}
+
+////////////////////////////////////////////////////////////////
+// This function is a filter:
+// Return the c character if c is a legal short name character
+// Return the '_' character if c is illegal
+////////////////////////////////////////////////////////////////
+static unsigned char illegal_short(unsigned char c)
+{
+   const unsigned char illegal_char [] =";+=[]â,\"*\\<>/?:|\0";
+   short i = 0;
+   while (illegal_char[i]!='\0')
+   {
+      if (c == illegal_char[i])
+         return '_';
+      i++;
+   }
+   return c;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// This function test if the string argument is a legal SFN (Short File Name)
+// and copies this name (removing the .) in the sfn_string argument.
+// Criteria for a Short File Name are:
+// - separator is '.' (extension is not mandatory)
+// - 1 <= name length <= 8
+// - 0 <= extension length <= 3
+// - no illegal character (see illega_short() function)
+// Return 1 if it string is a legal SFN
+// Return 0 if not legal SFN
+/////////////////////////////////////////////////////////////////////////////////
+static int is_short( char* string, 
+                     char* sfn_string)
+{
+    int s_size   = 0;
+    int dot_ext  = 0;       // dot offset in the filename
+    int name_len = 0;       // length of file name
+    int ext_len  = 0;       // length of extension
+    int i        = 0;
+    int sc_i     = 0;
+    char ch;
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] filename ");
+_puts( string );
+_tty_release_lock( 0 );
+#endif
+
+    if(string[0] == '.' && string[1] == '\0')
+    {
+        sfn_string[0] = '.';
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts(" converted to 8.3 SFN format : ");
+_puts( sfn_string );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+      return 1;
+   }
+
+   if(string[0] == '.' && string[1] == '.' && string[2] == '\0')
+   {
+      sfn_string[0] = '.';
+      sfn_string[1] = '.';
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts(" converted to 8.3 SFN format : ");
+_puts( string );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+      return 1;
+   }
+
+   sfn_string[11] = '\0';
+
+   while (string[s_size] != '\0')
+   {
+      if (string[s_size] == '.')
+      {
+         dot_ext = s_size;
+         ext_len = -1;
+      }
+      ext_len++;
+      s_size++;
+   }
+
+   if (dot_ext != 0)
+   {
+      name_len = s_size - ext_len - 1;
+   }
+   else
+   {
+      name_len = s_size;
+      ext_len = 0;
+   }
+
+   if ( ext_len > 3 || ( name_len > 8))
+   {
+      return 0;
+   }
+
+   if (dot_ext != 0)
+   {
+      while (i != ext_len)
+      {
+         ch = to_upper(string[dot_ext + 1 + i]);
+         ch = illegal_short(ch);
+         sfn_string[8+i] = ch;
+         i++;
+      } 
+   }
+   i = 0;
+   sc_i = 0;
+   while (i!= name_len)
+   {
+      ch = to_upper(string[i]);
+      ch = illegal_short(ch);
+      if (ch != '.')
+         sfn_string[sc_i++] = ch;
+      i++;
+   }
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts(" converted to 8.3 SFN format : ");
+_puts( sfn_string );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+   return 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+static int get_name_from_short( char* dir_entry,     // input:  SFN dir_entry
+                                char* entry_name )   // output: name
+{
+    unsigned int i   = 0;
+    unsigned int length = get_length(DIR_NAME);
+
+    while ( i < length )
+    {
+        entry_name[i] = dir_entry[i];
+        i++;
+    }
+    entry_name[i] = '\0';
+
+    return i;
+}
+///////////////////////////////////////////////////////////////////////////////
+static int get_name_from_long( char *dir_entry,    // input : LFN dir_entry
+                               char *entry_name)   // output : name
+{
+    unsigned int   entry_name_offset   = 0;
+    unsigned int   dir_entry_offset    = get_length(LDIR_ORD);
+    unsigned int   l_name_1            = get_length(LDIR_NAME_1);
+    unsigned int   l_name_2            = get_length(LDIR_NAME_2);
+    unsigned int   l_name_3            = get_length(LDIR_NAME_3);
+    unsigned int   l_attr              = get_length(LDIR_ATTR);
+    unsigned int   l_type              = get_length(LDIR_TYPE);
+    unsigned int   l_chksum            = get_length(LDIR_CHKSUM);
+    unsigned int   l_rsvd              = get_length(LDIR_RSVD);
+
+    unsigned int j            = 0;
+    unsigned int eof          = 0;
+
+    while ( (dir_entry_offset != DIR_ENTRY_SIZE)  && (!eof) )
+    {
+        while (j != l_name_1 && !eof )
+        {
+            if ( (dir_entry[dir_entry_offset] == 0x00) || 
+                 (dir_entry[dir_entry_offset] == 0xFF) )
+            {
+                eof = 1;
+                continue;
+            }
+            entry_name[entry_name_offset] = dir_entry[dir_entry_offset];
+            dir_entry_offset += 2;
+            j += 2;
+            entry_name_offset++;
+        }
+
+        dir_entry_offset += (l_attr + l_type + l_chksum);
+        j = 0;
+
+        while (j != l_name_2 && !eof )
+        {
+            if ( (dir_entry[dir_entry_offset] == 0x00) || 
+                 (dir_entry[dir_entry_offset] == 0xFF) )
+            {
+                eof = 1;
+                continue;
+            }
+            entry_name[entry_name_offset] = dir_entry[dir_entry_offset];
+            dir_entry_offset += 2;
+            j += 2;
+            entry_name_offset++;
+        }
+
+        dir_entry_offset += l_rsvd;
+        j = 0;
+
+        while (j != l_name_3 && !eof )
+        {
+            if ( (dir_entry[dir_entry_offset] == 0x00) || 
+                 (dir_entry[dir_entry_offset] == 0xFF) )
+            {
+                eof = 1;
+                continue;
+            }
+            entry_name[entry_name_offset] = dir_entry[dir_entry_offset];
+            dir_entry_offset += 2;
+            j += 2;
+            entry_name_offset++;
+        }
+    }
+    entry_name[entry_name_offset] = '\0';
+
+    return entry_name_offset;
+} // end get_name_from_long()
+
+////////////////////////////////////////////////////////////////////////////////////////
+// This function read the blocks defined by the cluster index argument, in a data 
+// region containing a directory to search the name of a file/firectory, 
+// and returns the cluster index of the file/directory when the name has been found.
+// Return cluster index if name found / Return -1 if not found,
+////////////////////////////////////////////////////////////////////////////////////////
+static int scan_directory( unsigned int   mode,        // mode for IOC driver
+                           unsigned int   cluster,     // cluster containing dir_entry 
+                           char*          file_name,   // searched file/directory name
+                           unsigned int*  file_size )  // file size
+{
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] enter _scan_directory() searching dir/file : ");
+_puts( file_name );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    char dir_entry[32];   // buffer to store a full directory_entry
+    char name_entry[14];  // buffer to store a 13 characters (partial) name
+
+    char sfn[12]            = {[0 ... 10] = ' ', '\0'};   // buffer for a Short File Name
+    unsigned int  is_sfn    = is_short(file_name, sfn);   // if file_name is short, sfn = 1     
+    unsigned int  offset    = 0;                          // byte offset in block
+    unsigned int  block_id  = fat.sectors_per_cluster;   // sector index initialisation       
+    unsigned int  lba       = cluster_to_lba(cluster);    
+    unsigned int  attr      = 0;                          // directory entry attribute
+    unsigned int  ord       = 0;                          // directory entry sequence
+    unsigned int  found     = 0;                          // name found
+    unsigned int  i;
+
+    for( i = 0 ; i < 32 ; i++ ) dir_entry[i]  = 0;
+    for( i = 0 ; i < 14 ; i++ ) name_entry[i] = 0;
+
+    // load first cluster sector from DATA region into FAT cache
+    // other sectors will be loaded inside loop as required
+    if( _ioc_read( mode,            // mode for IOC driver
+                   lba,             // sector index 
+                   fat.fat_cache,   // buffer address
+                   1 ) )            // one sector
+    {
+        _tty_get_lock( 0 );
+        _puts("[FAT ERROR] in scan directory() cannot read sector ");
+        _putd( lba );
+        _puts("\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+
+    fat.cache_lba = lba;
+
+    #if GIET_DEBUG_FAT
+    display_fat_cache();
+    #endif
+
+    // in this loop we scan all names in directory identified by cluster: 
+    // - the offset increment is an integer number of directory entry (32 bytes)
+    // - the exit condition is success (name found) or failure (end of directory) 
+    while( 1 )
+    {
+        // load a new sector if required
+        if (offset >= 512)              
+        {
+            if ( block_id )           // not a new cluster
+            {
+                lba += 1;
+                block_id --;
+            }
+            else					  // get next cluster
+            {
+                cluster = get_next_cluster_id( mode, cluster );
+
+                if ( cluster >= END_OF_CHAIN_CLUSTER  ) return END_OF_CHAIN_CLUSTER;
+
+                lba      = cluster_to_lba(cluster);
+                block_id = fat.sectors_per_cluster;
+            }
+            if( _ioc_read( mode,             // mode for IOC driver
+                           lba,              // sector index 
+                           fat.fat_cache,   // buffer address
+                           1 ) )             // one sector
+            {
+                _tty_get_lock( 0 );
+                _puts("[FAT ERROR] in scan directory() cannot read sector ");
+                _putd( lba );
+                _puts("\n");
+                _tty_release_lock( 0 );
+                return -1;
+            }
+            fat.cache_lba = lba;
+            block_id--;
+            offset = offset % 512;
+        }
+
+        // analyse a directory entry (pointed by fat.fat_cache + offset)
+        if ( !found )
+        { 
+            attr = read_entry( DIR_ATTR, fat.fat_cache + offset, 0);   
+            ord  = read_entry( LDIR_ORD, fat.fat_cache + offset, 0);
+
+            if ( is_sfn == 1 )		                  // searched name is short
+            {
+                if      ( (ord != FREE_ENTRY ) &&
+                          (ord != NO_MORE_ENTRY) &&
+                          (attr == ATTR_LONG_NAME_MASK) )    // LFN entry : skipped
+                {
+					offset     = offset + ((ord & 0xF) * DIR_ENTRY_SIZE);
+                    continue;
+                }
+                else if ( (attr != ATTR_LONG_NAME_MASK) && 
+                          (ord  != FREE_ENTRY) && 
+                          (ord  != NO_MORE_ENTRY ) )         // SFN entry : checked
+                {
+                    _memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE );    
+                    offset = offset + DIR_ENTRY_SIZE;
+                }
+                else if (ord == NO_MORE_ENTRY )              // end of directory : return
+                {
+                    return END_OF_CHAIN_CLUSTER;
+                }
+                else									     // free entry : skipped
+                {
+                    offset = offset + DIR_ENTRY_SIZE;
+                    continue;
+                }
+            }
+            else                                      // searched name is long
+            {
+                if( (attr == ATTR_LONG_NAME_MASK) && 
+                    (ord != FREE_ENTRY) &&
+                    (ord != NO_MORE_ENTRY) )                 // LFN entry : checked
+                {
+                    _memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE );    
+                    offset = offset + DIR_ENTRY_SIZE;
+                }
+                else if( (attr != ATTR_LONG_NAME_MASK) && 
+                         (ord  != FREE_ENTRY) && 
+                         (ord  != NO_MORE_ENTRY))			 // SFN entry : skipped
+                {
+                    offset = offset + DIR_ENTRY_SIZE;
+                    continue;
+                }
+                else if (ord == NO_MORE_ENTRY )				 // end of director : return
+                {
+                    return END_OF_CHAIN_CLUSTER;
+                }
+                else                                           // free entry : skipped
+                {
+                    offset = offset + DIR_ENTRY_SIZE;
+                    continue;
+                }
+            }
+
+            // testing the name extracted from dir entry
+            if ( is_sfn == 1 )                            // searched name is short
+            {
+                get_name_from_short( dir_entry, name_entry );
+
+                if ( _strncmp( (char*)sfn, (char*)name_entry, 13 ) == 0 )
+                {
+                    *file_size = read_entry( DIR_FILE_SIZE , dir_entry, 1 );
+                    return read_cluster( dir_entry );
+                }
+            }
+            else                                         // searched name is long
+            {
+                get_name_from_long( dir_entry, name_entry );
+
+                unsigned shift = ((ord & 0xf) - 1) * 13;
+                if ( _strncmp( (char*)(file_name + shift), (char*)name_entry, 13 ) == 0 )
+                {
+                    if( (ord & 0xf) == 1 )  found = 1;
+                    continue;
+                }
+                else								     // no matching : skip
+                {
+                    offset = offset + ((ord & 0xf) * DIR_ENTRY_SIZE);
+                }
+            }
+        } 
+        else    // file found
+        {
+            _memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE );    
+            offset     = offset + DIR_ENTRY_SIZE;
+            *file_size = read_entry( DIR_FILE_SIZE, dir_entry, 1 );
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] FILE FOUND\n");
+_tty_release_lock( 0 );
+#endif
+            return read_cluster( dir_entry );
+        }
+    }
+    return -1;
+} // end scan_directory()
+
+///////////////////////////////////////////////////////////////////////
+// This function analyses the pathname argument, from the character 
+// defined by the *nb_read argument.
+// It copies the found name (between '/') in the name[] buffer, 
+// and updates the nb_read argument.
+// Return 1 if name found, Return 0 if NUL character found, 
+///////////////////////////////////////////////////////////////////////
+static int get_name_from_path( char*          pathname,
+                               char*          name,
+                               unsigned int*  nb_read )	
+{
+    if ( pathname[*nb_read] == 0 ) return 0;
+
+    int i = (pathname[*nb_read] == '/')? (*nb_read) + 1 : *nb_read;
+    int j = 0;
+   
+    while(pathname[i] != '/' && pathname[i] != '\0')
+    {
+        name[j] = pathname[i];    
+        j++;
+        i++;
+    }
+    name[j] = 0;
+
+    if ( pathname[i] == '/' ) *nb_read += j+1;
+    else                      *nb_read += j;
+
+    return 1;
+}
+
+//////////////////////////////////////////////////////////////////////
+// This function create a new entry in a directory identified 
+// by "dir_cluster". The name is defined by "name".
+// The type (dir/file) is defined by "is_file".
+// Returns cluster index if success, Returns -1 if error.
+//////////////////////////////////////////////////////////////////////
+static int fat_create( char*           name,
+                       unsigned int    is_file,
+                       unsigned int    dir_cluster )
+{
+    _tty_get_lock( 0 );
+    _puts("\n[FAT ERROR] _fat_create() not implemented\n");
+    _tty_release_lock( 0 );
+    return 0;
+}  //end _fat_create()
+
+
+
+////////////// Extern functions //////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////
+// This function initializes the FAT structure, including the
+// files descriptors array, from informations found in the boot record.
+//////////////////////////////////////////////////////////////////////////
+// Return 0 if success, Return -1 if failure 
+//////////////////////////////////////////////////////////////////////////
+int _fat_init( unsigned int mode )   // mode for IOC driver
+{
+    unsigned int   n;
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] Enter _fat_init() / fat_cache_base = ");
+_putx( (unsigned int)fat.fat_cache );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // load Master Boot Record (sector 0) into fat cache
+    if ( _ioc_read( mode,             // mode for IOC driver
+                    0,                // sector index 
+                    fat.fat_cache,    // buffer address
+                    1 ) )             // one sector
+    { 
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_init() cannot load Boot Sector\n"); 
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    fat.cache_lba = 0;
+    
+    // checking Boot sector integrity
+    if( MBR_SIGNATURE_VALUE != read_entry( MBR_SIGNATURE_POSITION, fat.fat_cache, 1))
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] Boot sector not recognized or corrupt \n"); 
+        _tty_release_lock( 0 );
+        return -1;  
+    }
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] Boot Sector Loaded\n");
+_tty_release_lock( 0 );
+#endif
+
+    // initialise fat descriptor from Boot sector
+    fat.partition_lba     = read_entry( FIRST_PARTITION_BEGIN_LBA, fat.fat_cache, 1 );
+    fat.partition_sectors = read_entry( FIRST_PARTITION_SIZE,      fat.fat_cache, 1 );
+
+    // load Partition Boot Record (first partition sector) into fat cache
+    if ( _ioc_read( mode,                 // mode for IOC driver
+                    fat.partition_lba,   // sector index
+                    fat.fat_cache,       // buffer address
+                    1 ) )                 // one sector
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_init() cannot load block ");
+        _putd( fat.partition_lba );
+        _puts("\n"); 
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    fat.cache_lba = fat.partition_lba;
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] Partition First Sector Loaded\n");
+_tty_release_lock( 0 );
+#endif
+
+
+    // checking various FAT32 assuptions from boot sector
+    if( read_entry( BPB_BYTSPERSEC, fat.fat_cache, 1 ) != 512 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] The sector size must be 512 bytes\n");
+        _tty_release_lock( 0 );
+        return -1;  
+    }
+    if( read_entry( BPB_RSVDSECCNT, fat.fat_cache, 1 ) != 32 ) 
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] The RSVD region in FAT32 must be 32 sectors\n");
+        _tty_release_lock( 0 );
+        return -1;  
+    }
+    if( read_entry( BPB_NUMFATS, fat.fat_cache, 1 ) != 1 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] The number of FAT copies in FAT region must be 1\n");
+        _tty_release_lock( 0 );
+        return -1;  
+    }
+    if( (read_entry( BPB_FAT32_FATSZ32, fat.fat_cache, 1 ) & 0xF) != 0 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] The FAT region in FAT32 must be multiple of 32 sectors\n");
+        _tty_release_lock( 0 );
+        return -1;  
+    }
+
+    if( read_entry( BPB_FAT32_ROOTCLUS, fat.fat_cache, 1 ) != 2 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] The first cluster index must be 2\n");
+        _tty_release_lock( 0 );
+        return -1;  
+    }
+
+    // initialise fat descriptor from partition first sector
+    fat.sectors_per_cluster = read_entry( BPB_SECPERCLUS, fat.fat_cache, 1 );
+    fat.sector_size         = read_entry( BPB_BYTSPERSEC, fat.fat_cache, 1 );
+    fat.cluster_size        = fat.sectors_per_cluster * 512;
+    fat.fat_sectors         = read_entry( BPB_FAT32_FATSZ32, fat.fat_cache, 1 );
+    fat.data_lba            = 32 + fat.fat_sectors + fat.partition_lba;
+    fat.initialised         = FAT_INITIALISED;
+
+    // initialise file descriptor array
+    for( n = 0 ; n < GIET_OPEN_FILES_MAX ; n++ ) fat.fd[n].used = 0;
+
+#if (GIET_DEBUG_FAT == 1)
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] Exit _fat_init()\n");
+_tty_release_lock( 0 );
+#endif
+
+    return 0;
+}  // end _fat_init()
+
+/////////////////
+void _fat_print()
+{
+    _puts("\n################################ FAT32 ###############################");  
+    _puts("\nFAT initialised                "); _putx( fat.initialised );
+    _puts("\nSector Size  (bytes)           "); _putx( fat.sector_size );
+    _puts("\nSectors per cluster            "); _putx( fat.sectors_per_cluster );
+    _puts("\nPartition size (sectors)       "); _putx( fat.partition_sectors );
+    _puts("\nPartition first lba            "); _putx( fat.partition_lba ); 
+    _puts("\nData region first lba          "); _putx( fat.data_lba );
+    _puts("\nNumber of sectors for one FAT  "); _putx( fat.fat_sectors );
+    _puts("\n######################################################################\n");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This function checks that the kernel FAT structure has been initialised,
+// and makes the FAT initialisation if it is the first user open request. 
+// This function searches a file identified by the "pathname" argument.
+// It starts from root (cluster 2) to scan successively each subdirectory.
+// When the file is not found, but the path is found, and "creat" is set,
+// a new file is created and introduced in the directory.
+// Finally, it sets a new open file in the file descriptors array.
+///////////////////////////////////////////////////////////////////////////////
+// Returns file descriptor index if success, returns -1 if error.
+///////////////////////////////////////////////////////////////////////////////
+int _fat_open( unsigned     mode,
+               char*        pathname,
+               unsigned int creat )
+{
+    char                 name[256];    // buffer for one name in pathname
+    unsigned int         nb_read;	   // number of characters written in name[] 
+    unsigned int         cluster;      // current cluster index when scanning FAT
+    unsigned int         dir_cluster;  // previous cluster index when scanning FAT
+    unsigned int         fd_id;        // index when scanning file descriptors array
+    unsigned int         file_size;    // number of bytes
+    unsigned int         last_name;    // directory containing file name is reached
+    
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] enter _fat_open() for file ");
+_puts( pathname );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // check FAT initialised
+    if( fat.initialised != FAT_INITIALISED )
+    {
+        if ( _fat_init( mode ) )
+        {
+            _puts("[FAT ERROR] Cannot initialize FAT descriptor fom Boot Sector\n");
+            _exit();
+        }
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] FAT initialisation completed at cycle ");
+_putd(_get_proctime());
+_puts("\n");
+_fat_print();
+_tty_release_lock( 0 );
+#endif
+    }
+ 
+    // Scan the directories, starting from the root directory (cluster 2)
+    // - The get_name_from_path() function extracts (successively) 
+    //   each directory name from the pathname, and store it in name[] buffer
+    // - The scan_directory() function scan one (or several) cluster(s) containing 
+    //   a directory looking for name[], and return the cluster index
+    //   corresponding to the directory/file found.
+    nb_read     = 0;
+    cluster     = 2;
+    last_name   = 0;
+    while ( get_name_from_path( pathname, name, &nb_read) )
+    {
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] _fat_open : search dir/file : ");
+_puts( name );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+        // test if we reach the last name (file name)
+        if( pathname[nb_read] == 0 )  
+        {
+            last_name   = 1;
+            dir_cluster = cluster;
+        }
+
+        // scan current directory
+        cluster  = scan_directory( mode, cluster, name, &file_size );
+
+        if( cluster == END_OF_CHAIN_CLUSTER && last_name && creat )
+        {
+            cluster = fat_create( name, 1, dir_cluster );
+        }
+        else if ( cluster == END_OF_CHAIN_CLUSTER )
+        {
+            _tty_get_lock( 0 );
+            _puts("\n[FAT ERROR] in _fat_open() for file ");
+            _puts( pathname );
+            _puts(" : cannot found name ");
+            _puts( name );
+            _puts("\n");
+            _tty_release_lock( 0 );
+            return -1;
+        }
+    }
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] File ");
+_puts( pathname );
+_puts(" found\n");
+_tty_release_lock( 0 );
+#endif
+
+    // check the next value for cluster index found
+    unsigned next = get_next_cluster_id( mode, cluster );
+
+    if ( (next != BAD_CLUSTER) && (next != FREE_CLUSTER) )
+    {
+        // Search an empty slot scanning open file descriptors array
+        fd_id = 0;
+        while ( fat.fd[fd_id].used != 0 && fd_id < GIET_OPEN_FILES_MAX )
+        {
+            fd_id++;
+        }
+
+        // set file descriptor if found empty slot
+        if ( fd_id < GIET_OPEN_FILES_MAX )
+        {
+            fat.fd[fd_id].used          = 1;
+            fat.fd[fd_id].first_cluster = cluster;
+            fat.fd[fd_id].file_size     = file_size;
+            _strcpy( fat.fd[fd_id].name, pathname );
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] file  ");
+_puts( pathname );
+_puts(" open with fd_id = ");
+_putd( fd_id );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+            return fd_id;
+        }
+        else
+        {
+            _tty_get_lock( 0 );
+            _puts("\n[FAT ERROR] in _fat_open() for file ");
+            _puts( pathname );
+            _puts(" : file descriptor array full\n ");
+            _tty_release_lock( 0 );
+            return -1;
+        }
+    }
+    else
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_open() for file ");
+        _puts( pathname );
+        _puts(" : file found, but bad cluster\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+} // end _fat_open()
+
+///////////////////////////////////////////////////////////////////////////////
+// For an open file, identified by the file descriptor index, transfer 
+// an integer number of sectors from block device to a memory buffer.
+// If the number of requested sectors exceeds the file size, it is reduced.
+///////////////////////////////////////////////////////////////////////////////
+// Returns number of sectors transfered if success, < 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+int _fat_read( unsigned int mode,       // mode for IOC driver
+               unsigned int fd_id,      // file descriptor
+               void*        buffer,     // target buffer base address
+               unsigned int count,      // number of sector to read
+               unsigned int offset )    // nuber of sectors to skip in file
+{
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] Enter _fat_read() for file ");
+_puts( fat.fd[fd_id].name );
+_puts("\n - buffer base     = ");
+_putx( (unsigned int)buffer );
+_puts("\n - skipped sectors = ");
+_putd( offset );
+_puts("\n - read sectors    = "); 
+_putd( count );
+_tty_release_lock( 0 );
+#endif
+
+    unsigned int spc = fat.sectors_per_cluster;
+
+    unsigned int file_size;         // number of bytes in file
+    unsigned int file_sectors;      // number of sectors in file
+    unsigned int total_sectors;     // actual number of sectors to be transfered
+    unsigned int cluster;           // cluster index 
+    unsigned int clusters_to_skip;  // number of clusters to skip because offset
+    unsigned int sectors_to_skip;   // number of sectors to skip in first iteration
+
+    // compute file size as a number of sectors 
+    file_size    = fat.fd[fd_id].file_size;
+    if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1;
+    else                     file_sectors = (file_size >> 9); 
+
+    // arguments checking
+    if ( fd_id >= GIET_OPEN_FILES_MAX )
+    { 
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_read() : illegal file descriptor index\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    if ( fat.fd[fd_id].used != 1 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_read() : file not open\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    if ( ((unsigned int)buffer & 0x1FF) != 0 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_read() : memory buffer not sector aligned\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    if ( offset >= file_sectors )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] offset larger than number of sectors in file\n");
+        _puts(" - offset       = ");
+        _putd( offset );
+        _puts(" - file_sectors = ");
+        _putd( file_sectors );
+        _tty_release_lock( 0 );
+        return -1;
+    }
+
+    // compute total number of sectors to read
+    if ( file_sectors < (offset + count) ) total_sectors = file_sectors - offset;
+    else                                   total_sectors = count;
+
+    // compute clusters and sectors to be skipped
+    clusters_to_skip = offset / spc;
+    sectors_to_skip  = offset % spc;
+    
+    // get first cluster index 
+    cluster = fat.fd[fd_id].first_cluster;
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n - first cluster   = ");
+_putd( cluster );   
+_puts("\n - skiped clusters = ");
+_putd( clusters_to_skip );   
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // compute index of first cluster to be loaded
+    // as we may need to scan the FAT, we use the kernel mode
+    while ( clusters_to_skip )
+    {
+        cluster = get_next_cluster_id( IOC_KERNEL_MODE, cluster );
+        clusters_to_skip--;
+    }
+
+    // variables used in the loop on clusters
+    int             todo_sectors;   // number of sectors still to be loaded
+    unsigned int    lba;            // first sector index on device
+    unsigned int    iter_sectors;   // number of sectors to load in iteration
+    char*           dst;            // pointer on target buffer
+
+    // initialize these variables for the first iteration 
+    todo_sectors  = total_sectors;
+    dst           = (char*)buffer;
+    lba           = cluster_to_lba(cluster) + sectors_to_skip;
+    if( total_sectors < (spc - sectors_to_skip) ) iter_sectors = total_sectors;
+    else                                          iter_sectors = spc - sectors_to_skip; 
+
+    // loop on the clusters
+    while ( todo_sectors > 0 )
+    {
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] _fat_read() IOC request : buf = ");
+_putx( (unsigned int)dst );
+_puts(" / lba = ");
+_putd( lba );
+_puts(" / sectors = "); 
+_putd( iter_sectors );
+_puts("\n");  
+_tty_release_lock( 0 );
+#endif
+
+        if( _ioc_read( mode,              // mode for IOC driver
+                       lba,               // first sector index 
+                       dst,               // buffer address
+                       iter_sectors ) )   // number of sectors
+        {
+            _tty_get_lock( 0 );
+            _puts("\n[FAT ERROR] in _fat_read() cannot load block ");
+            _putd( lba );
+            _puts("\n"); 
+            _tty_release_lock( 0 );
+            return -1;
+        }
+         
+        // update variables for next iteration
+        cluster      = get_next_cluster_id( mode, cluster );
+        todo_sectors = todo_sectors - iter_sectors;
+        dst          = dst + (iter_sectors << 9);
+        lba          = cluster_to_lba(cluster);
+        if ( todo_sectors > spc ) iter_sectors = spc;
+        else                      iter_sectors = todo_sectors;
+    }
+         
+    // returns number of sectors actually transfered
+    return total_sectors;
+
+}  // end _fat_read() 
+
+///////////////////////////////////////////////////////////////////////////////
+// For an open file, identified by the file descriptor index, transfer 
+// an integer number of sectors from a memory buffer to block device.
+// Allocate new clusters if the offset+count larger than current file size,
+// but the offset should be smaller than the current file size...
+// - fat    : pointer on FAT 
+// - mode   : mode for the IOC driver
+// - fd_id  : open file descriptor index  
+// - fd_id  : open file descriptor index  
+// - buffer : base address of the memory buffer (must be sector aligned)
+// - offset : number of sectors to skip in file
+// - count  : number of sectors to be written.
+///////////////////////////////////////////////////////////////////////////////
+// Returns number of sectors written if success, < 0 if error.
+///////////////////////////////////////////////////////////////////////////////
+int _fat_write( unsigned int mode,       // mode for IOC driver
+                unsigned int fd_id,      // file descriptor
+                void*        buffer,     // target buffer base address
+                unsigned int count,      // number of sector to write
+                unsigned int offset )    // nuber of sectors to skip in file
+{
+
+    unsigned int spc = fat.sectors_per_cluster;
+
+    unsigned int file_size;         // number of bytes in file
+    unsigned int file_sectors;      // number of sectors in file
+    unsigned int cluster;           // cluster index 
+    unsigned int clusters_to_skip;  // number of clusters to skip because offset
+    unsigned int sectors_to_skip;   // number of sectors to skip in first iteration
+    unsigned int allocate;          // need allocate or not
+
+    // compute file size as a number of sectors 
+    file_size    = fat.fd[fd_id].file_size;
+    if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1;
+    else                     file_sectors = (file_size >> 9); 
+    
+    allocate = ( ((count + offset) / spc) > (file_sectors / spc) );
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] Enter _fat_write() for file ");
+_puts( fat.fd[fd_id].name );
+_puts("\n - buffer base     = ");
+_putx( (unsigned int)buffer );
+_puts("\n - skipped sectors = ");
+_putd( offset );
+_puts("\n - write sectors    = "); 
+_putd( count );
+_puts("\n - file size (sectors)  = "); 
+_putd( file_sectors );
+_puts("\n - need allocate = "); 
+allocate ? _puts( "True" ) : _puts( "False");
+_tty_release_lock( 0 );
+#endif
+
+    if ( allocate  )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_write() : \n");
+        _puts("we need to allocate more cluster... But this function is not implemented\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    // arguments checking
+    if ( fd_id >= GIET_OPEN_FILES_MAX )
+    { 
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_write() : illegal file descriptor index\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    if ( fat.fd[fd_id].used != 1 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_write() : file not open\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    if ( ((unsigned int)buffer & 0x1FF) != 0 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_write() : memory buffer not sector aligned\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+
+    // compute clusters and sectors to be skipped
+    clusters_to_skip = offset / spc;
+    sectors_to_skip  = offset % spc;
+    
+    // get first cluster index 
+    cluster = fat.fd[fd_id].first_cluster;
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n - first cluster   = ");
+_putd( cluster );   
+_puts("\n - skiped clusters = ");
+_putd( clusters_to_skip );   
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // compute index of first cluster to be loaded
+    // as we may need to scan the FAT, we use the kernel mode
+    while ( clusters_to_skip )
+    {
+        cluster = get_next_cluster_id( IOC_KERNEL_MODE, cluster );
+        clusters_to_skip--;
+    }
+
+    // variables used in the loop on clusters
+    int             todo_sectors;   // number of sectors still to be loaded
+    unsigned int    lba;            // first sector index on device
+    unsigned int    iter_sectors;   // number of sectors to load in iteration
+    char*           src;            // pointer on target buffer
+
+    // initialize these variables for the first iteration 
+    todo_sectors  = count;
+    src           = (char*)buffer;
+    lba           = cluster_to_lba(cluster) + sectors_to_skip;
+    if( count < (spc - sectors_to_skip) ) iter_sectors = count;
+    else                                  iter_sectors = spc - sectors_to_skip; 
+
+    // loop on the clusters
+    while ( todo_sectors > 0 )
+    {
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] _fat_write() IOC request : buf = ");
+_putx( (unsigned int)src );
+_puts(" / lba = ");
+_putd( lba );
+_puts(" / sectors = "); 
+_putd( iter_sectors );
+_puts("\n");  
+_tty_release_lock( 0 );
+#endif
+
+        if( _ioc_write( mode,              // mode for IOC driver
+                        lba,               // first sector index 
+                        src,               // buffer address
+                        iter_sectors ) )   // number of sectors
+        {
+            _tty_get_lock( 0 );
+            _puts("\n[FAT ERROR] in _fat_write() cannot write block ");
+            _putd( lba );
+            _puts("\n"); 
+            _tty_release_lock( 0 );
+            return -1;
+        }
+         
+        // update variables for next iteration
+        cluster      = get_next_cluster_id( mode, cluster );
+        todo_sectors = todo_sectors - iter_sectors;
+        src          = src + (iter_sectors << 9);
+        lba          = cluster_to_lba(cluster);
+        if ( todo_sectors > spc ) iter_sectors = spc;
+        else                      iter_sectors = todo_sectors;
+    }
+         
+    // returns number of sectors actually transfered
+    return count;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// Return stats of a file identified by "fd". 
+// (Only the file_size in sectors for this moment)
+/////////////////////////////////////////////////////////////////////////////////
+// Returns file size (on sectors) on success, -1 on failure.
+/////////////////////////////////////////////////////////////////////////////////
+int _fat_fstat( unsigned int fd_id )
+{
+    unsigned int file_size    = 0;
+    unsigned int file_sectors = 0;
+
+    if( (fd_id < GIET_OPEN_FILES_MAX) )
+    {
+        file_size = fat.fd[fd_id].file_size;
+
+        if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1;
+        else                     file_sectors = (file_size >> 9); 
+
+        return file_sectors;
+    }
+    else
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_fstat() : illegal file descriptor index\n");
+        _tty_release_lock( 0 );
+        return -1;
+    } 
+} // end _fat_fstat()
+
+/////////////////////////////////////////////////////////////////////////////////
+// Close the file identified by the file_descriptor index. 
+/////////////////////////////////////////////////////////////////////////////////
+// Returns 0 on success, -1 on failure.
+/////////////////////////////////////////////////////////////////////////////////
+int _fat_close( unsigned int fd_id )
+{
+    if( (fd_id < GIET_OPEN_FILES_MAX) )
+    {
+        fat.fd[fd_id].used = 0;
+        return 0;
+    }
+    else
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_close() : illegal file descriptor index\n");
+        _tty_release_lock( 0 );
+        return -1;
+    } 
+} // end fat_close()
+
+/////////////////////////////////////////////////////////////////////////////////////
+// The following function implement the user_level system call.
+// The flags argument is nor used, as file access modes are not implemented yet.
+/////////////////////////////////////////////////////////////////////////////////////
+// Return the file descriptor index if success / return -1 if failure
+/////////////////////////////////////////////////////////////////////////////////////
+int _fat_user_open( char*  pathname,         // absolute pathname from root
+                    unsigned int flags )     // unused: TODO
+{
+    return _fat_open( IOC_KERNEL_MODE,       // we KERNEL_MODE, because
+                      pathname,              // we need to write into FAT cache
+                      0 );       
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// The following function implement the user_level system call.
+// This function should be modified to respect the UNIX specification 
+/////////////////////////////////////////////////////////////////////////////////////
+// Return number of sectors actually transfered if success / return -1 if failure
+/////////////////////////////////////////////////////////////////////////////////////
+int _fat_user_read( unsigned int fd,        // file descriptor index
+                    void*        buffer,    // destination buffer
+                    unsigned int count,     // number of sectors to read
+                    unsigned int offset )   // number of sectors to skip
+{
+    return _fat_read( IOC_USER_MODE,
+                      fd,
+                      buffer,  
+                      count,  
+                      offset );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// The following function implement the user_level system call.
+// This function should be modified to respect the UNIX specification. 
+/////////////////////////////////////////////////////////////////////////////////////
+// Return number of sectors actually transfered if success / return -1 if failure
+/////////////////////////////////////////////////////////////////////////////////////
+int _fat_user_write( unsigned int fd,       // file descriptor
+                     void*        buffer,   // source buffer
+                     unsigned int count,    // number of sectors to write
+                     unsigned int offset )  // number of sectors to skip on file
+{
+    return _fat_write( IOC_USER_MODE,
+                       fd,
+                       buffer,  
+                       count,  
+                       offset );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+int _fat_user_lseek( unsigned int fd_id,
+                     unsigned int offset,
+                     unsigned int whence )
+{
+    _tty_get_lock( 0 );
+    _puts("[GIET ERROR] _fat_user_lseek function not implemented\n");
+    _tty_release_lock( 0 );
+    _exit();
+    return 0;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_fat32/fat32.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_fat32/fat32.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_fat32/fat32.h	(revision 283)
@@ -0,0 +1,214 @@
+////////////////////////////////////////////////////////////////////////////
+// File     : fat32.h 
+// Date     : 01/09/2013
+// Author   : Marco Jankovic / Alain Greiner
+// Copyright (c) UPMC-LIP6
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef _FAT32_H
+#define _FAT32_H
+
+#include "giet_config.h"
+
+/*************** Partition Boot Sector Format ******************************************/
+//                                     offset |  length
+#define BS_JMPBOOT                          0 ,  3
+#define BS_OEMNAME                          3 ,  8
+#define BPB_BYTSPERSEC                     11 ,  2
+#define BPB_SECPERCLUS                     13 ,  1
+#define BPB_RSVDSECCNT                     14 ,  2
+#define BPB_NUMFATS                        16 ,  1
+#define BPB_ROOTENTCNT                     17 ,  2
+#define BPB_TOTSEC16                       19 ,  2
+#define BPB_MEDIA                          21 ,  1
+#define BPB_FATSZ16                        22 ,  2
+#define BPB_SECPERTRK                      24 ,  2
+#define BPB_NUMHEADS                       26 ,  2
+#define BPB_HIDDSEC                        28 ,  4
+#define BPB_TOTSEC32                       32 ,  4
+#define BPB_PARTITION_TABLE               446 , 64 
+
+// FAT 32
+#define BPB_FAT32_FATSZ32                  36 ,  4
+#define BPB_FAT32_EXTFLAGS                 40 ,  2
+#define BPB_FAT32_FSVER                    42 ,  2
+#define BPB_FAT32_ROOTCLUS                 44 ,  4
+#define BPB_FAT32_FSINFO                   48 ,  2
+#define BPB_FAT32_BKBOOTSEC                50 ,  2
+#define BS_FAT32_DRVNUM                    64 ,  1
+#define BS_FAT32_BOOTSIG                   66 ,  1
+#define BS_FAT32_VOLID                     67 ,  4
+#define BS_FAT32_VOLLAB                    71 , 11
+#define BS_FAT32_FILSYSTYPE                82 ,  8
+
+// Partitions
+#define FIRST_PARTITION_ACTIVE            446 ,  8
+#define FIRST_PARTITION_BEGIN_LBA         454 ,  4
+#define FIRST_PARTITION_SIZE              458 ,  4 
+#define SECOND_PARTITION_ACTIVE           462 ,  8
+#define SECOND_PARTITION_BEGIN_LBA        470 ,  4
+#define SECOND_PARTITION_SIZE             474 ,  4
+#define THIRD_PARTITION_ACTIVE            478 ,  8
+#define THIRD_PARTITION_BEGIN_LBA         486 ,  4
+#define THIRD_PARTITION_SIZE              490 ,  4
+#define FOURTH_PARTITION_ACTIVE           494 ,  8
+#define FOURTH_PARTITION_BEGIN_LBA        502 ,  4
+#define FOURTH_PARTITION_SIZE             506 ,  4    
+/***************************************************************************************/
+
+#define MBR_SIGNATURE_POSITION            510 , 2
+#define MBR_SIGNATURE_VALUE               0xAA55  
+
+/************** FAT_FS_INFO SECTOR  ****************************************************/
+#define FS_SIGNATURE_VALUE_1              0x52526141
+#define FS_SIGNATURE_VALUE_2              0x72724161
+#define FS_SIGNATURE_VALUE_3              0x000055AA  
+#define FS_SIGNATURE_POSITION_1           0   , 4  
+#define FS_SIGNATURE_POSITION_2           484 , 4
+#define FS_SIGNATURE_POSITION_3           508 , 4  
+#define FS_FREE_CLUSTER                   492 , 4
+#define FS_FREE_CLUSTER_HINT              496 , 4
+/***************************************************************************************/
+
+#define DIR_ENTRY_SIZE          32
+                   
+/******* Directory Entry Structure (32 bytes) ******************************************/
+//                          offset | length
+#define DIR_NAME                 0 , 11   // dir_entry name
+#define DIR_ATTR                11 ,  1   // attributes
+#define DIR_NTRES               12 ,  1   // reserved for the OS        
+#define DIR_CRT_TIMES_TENTH     13 ,  1 
+#define DIR_FST_CLUS_HI         20 ,  2   // cluster index 16 MSB bits
+#define DIR_WRT_TIME            22 ,  2   // time of last write
+#define DIR_WRT_DATE            24 ,  2   // date of last write
+#define DIR_FST_CLUS_LO         26 ,  2   // cluster index 16 LSB bit
+#define DIR_FILE_SIZE           28 ,  4   // file size (up to 4 giga bytes)
+/***************************************************************************************/
+
+/******* LFN Directory Entry Structure  (32 bytes) *************************************/
+//                          offset | length
+#define LDIR_ORD                 0 ,  1   // Sequence number (from 0x01 to 0x0f)    
+#define LDIR_NAME_1              1 , 10   // name broken into 3 parts 
+#define LDIR_ATTR               11 ,  1   // attributes (must be 0x0F) 
+#define LDIR_TYPE               12 ,  1   // directory type (must be 0x00)
+#define LDIR_CHKSUM             13 ,  1   // checksum of name in short dir  
+#define LDIR_NAME_2             14 , 12 
+#define LDIR_RSVD               26 ,  2   // artifact of previous fat (must be 0)
+#define LDIR_NAME_3             28 ,  4   
+/***************************************************************************************/
+
+/***********************  DIR_ATTR values  (attributes) ********************************/  
+#define ATTR_READ_ONLY          0x01
+#define ATTR_HIDDEN             0x02
+#define ATTR_SYSTEM             0x04
+#define ATTR_VOLUME_ID          0x08
+#define ATTR_DIRECTORY          0x10
+#define ATTR_ARCHIVE            0x20
+#define ATTR_LONG_NAME_MASK     0x0f      // READ_ONLY|HIDDEN|SYSTEM|VOLUME_ID
+/***************************************************************************************/
+
+/********************* DIR_ORD special values ******************************************/
+#define FREE_ENTRY              0xE5     // this entry is free in the directory
+#define NO_MORE_ENTRY           0x00     // no more entry in the directory
+/***************************************************************************************/
+
+/******************** CLuster Index Special Values *************************************/
+#define FREE_CLUSTER            0x00000000
+#define RESERVED_CLUSTER        0x00000001
+#define BAD_CLUSTER             0x0FFFFFF7
+#define END_OF_CHAIN_CLUSTER    0x0ffffff8
+/***************************************************************************************/
+
+#define FAT_INITIALISED         0xBABEF00D
+
+/************ This struct defines a file descriptor ************************************/
+typedef struct file_descriptor_s
+{
+   unsigned int  used;                      // descriptor contains an open file
+   unsigned int  first_cluster;             // first cluster index in partition
+   unsigned int  file_size;                 // number of bytes    
+   char          name[244];                 // pathname
+}  file_desc_t;
+/***************************************************************************************/
+
+/************ This struct describes a FAT32 partition **********************************/
+typedef struct fat32_fs_s
+{
+    char            fat_cache[512];          // FAT cache: 1 sector = 128 cluster indexes 
+    file_desc_t     fd[GIET_OPEN_FILES_MAX]; // file descriptors array
+    unsigned int    initialised;             // contains 0xBABEF00D when FAT initialised
+    unsigned int    sector_size;             // number of bytes (power of 2)
+    unsigned int    sectors_per_cluster;     // power of 2 (must be greater than 4)
+    unsigned int    cluster_size;            // sector_size * sector_per_cluster (bytes)
+    unsigned int    fat_sectors;             // number of sectors occupied by one FAT copy
+    unsigned int    partition_sectors;       // total number of sectors (RESVD + FAT + DATA)
+    unsigned int    partition_lba;           // lba of first partiton sector 
+    unsigned int    data_lba;                // lba of first data sector  
+    unsigned int    cache_lba;               // lba of sector loaded in fat_cache
+} fat32_fs_t;
+/***************************************************************************************/
+
+/*********************** Export Functions  *********************************************/
+
+extern void _fat_print();
+
+// functions used for low level access to fat
+// (move sectors between block device and system buffers)
+
+extern int _fat_init(  unsigned int mode );        // mode for IOC driver
+
+extern int _fat_open(  unsigned int mode,          // mode for IOC driver
+                       char*  pathname,            // file pathname from root
+                       unsigned int create );      // create new file if non zero
+
+extern int _fat_read(  unsigned int mode,          // mode for IOC driver
+                       unsigned int fd_id,         // file descriptor index 
+                       void*        buffer,        // destination buffer
+                       unsigned int count,  	      // number of sectors to read
+                       unsigned int offset );      // offset sector in file
+
+extern int _fat_write( unsigned int mode,         // mode for IOC driver
+                       unsigned int fd_id,        // file descriptor index
+                       void*        buffer,		  // source buffer
+                       unsigned int count,        // number of sectors to write
+                       unsigned int offset );     // offset sector in file
+
+extern int _fat_fstat( unsigned int fd_id );      // file descriptor index
+
+extern int _fat_close( unsigned int fd_id );      // file descriptor index
+
+
+// functions used by user system calls
+// (should move bytes between system buffers and user buffers) 
+
+extern int _fat_user_open(  char*        pathname,  // file pathname from root
+                            unsigned int flags );   // unused
+
+extern int _fat_user_read(  unsigned int fd_id,     // file descriptor index
+                            void*        buffer,    // destination buffer
+                            unsigned int count,     // number of sectors to read
+                            unsigned int offset );  // number of sectors to skip in file
+
+extern int _fat_user_write( unsigned int fd_id,     // file descriptor index
+                            void*        buffer,    // source buffer
+                            unsigned int count,     // number of sectors to write
+                            unsigned int offset );  // number of sectors to skip in file
+
+extern int _fat_user_lseek( unsigned int fd_id,
+                            unsigned int offset,
+                            unsigned int whence );  
+
+/***************************************************************************************/
+
+
+#endif
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/ctx_handler.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/ctx_handler.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/ctx_handler.c	(revision 283)
@@ -0,0 +1,200 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// File     : ctx_handler.c
+// Date     : 01/04/2012
+// Authors  : alain greiner & joel porquet
+// Copyright (c) UPMC-LIP6
+/////////////////////////////////////////////////////////////////////////////////////////
+// The ctx_handler.h and ctx_handler.c files are part of the GIET-VM nano-kernel.
+// This code is used to support context switch when several tasks are executing
+// in time multiplexing on a single processor.
+// The tasks are statically allocated to a processor in the boot phase, and
+// there is one private scheduler per processor. Each sheduler occupies 4K bytes, 
+// and contains up to 14 task contexts (task_id is from 0 to 13).
+// The task context [14] is reserved for the "idle" task that does nothing, and
+// is launched by the scheduler when there is no other runable task.
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <tim_driver.h>
+#include <xcu_driver.h>
+#include <tty_driver.h>
+#include <utils.h>
+#include <ctx_handler.h>
+#include <mapping_info.h>
+#include <sys_handler.h>
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// A task context is an array of 64 words = 256 bytes. 
+// It contains copies of processor registers (when the task is preempted):
+// - GPR[i], generally stored in slot (i). $0, $26 & $27 are not saved.
+// - HI & LO registers
+// - CP0 registers: EPC, SR, CR, BVAR 
+// - CP2 registers : PTPR 
+// It contains some general informations associated to the task:
+// - TTY    : TTY channel global index
+// - NIC    : NIC channel global index
+// - CMA    : CMA channel global index
+// - HBA    : HBA channel global index
+// - DMA    : DMA channel local index
+// - TIM    : TIM channel local index
+// - PTAB   : page table virtual base address 
+// - LTID   : Task local index (in scheduler)
+// - VSID   : Virtual space index
+// - RUN    : Task state (0 => sleeping / 1 => runnable ) 
+// - TRDID  : Thread ID index (in vspace)
+//
+// ctx[0]<- ***|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC  |ctx[40]<- TTY
+// ctx[1]<- $1 |ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR   |ctx[41]<- DMA
+// ctx[2]<- $2 |ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- SR   |ctx[42]<- NIC
+// ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIM
+// ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- PTAB |ctx[44]<- HBA
+// ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- LTID |ctx[45]<- CMA 
+// ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- VSID |ctx[46]<- GTID
+// ctx[7]<- $7 |ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- PTPR |ctx[47]<- RUN
+//
+// ctx[48]<- TRDID
+//////////////////////////////////////////////////////////////////////////////////////////
+
+extern void _task_switch(unsigned int *, unsigned int *);
+
+/////////////////////////////////////////////////////////////////////////////////
+//    _ctx_switch()
+// This function performs a context switch between the running task
+// and  another task, using a round-robin sheduling policy between all
+// tasks allocated to a given processor (static allocation).
+// It selects the next runable task to resume execution. 
+// If the only runable task is the current task, return without context switch.
+// If there is no runable task, the scheduler switch to the default "idle" task.
+//
+// Implementation note
+// The return address contained in $31 is saved in the current task context
+// (in the ctx[31] slot), and the function actually returns to the address
+// contained in the ctx[31] slot of the next task context.
+/////////////////////////////////////////////////////////////////////////////////
+void _ctx_switch() 
+{
+    // get scheduler address
+    static_scheduler_t* psched = (static_scheduler_t*)_get_sched();
+
+    // get number of tasks allocated to scheduler
+    unsigned int tasks = psched->tasks;
+
+    // get current task index
+    unsigned int curr_task_id = psched->current;
+
+    // select the next task using a round-robin policy
+    unsigned int next_task_id;
+    unsigned int tid;
+    unsigned int found = 0;
+
+    for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++) 
+    {
+        next_task_id = tid % tasks;
+        // test if the task is runable
+        if ( psched->context[next_task_id][CTX_RUN_ID] ) 
+        {
+            found = 1;
+            break;
+        }
+    }
+
+    // launch "idle" task if no runable task
+    if (found == 0) 
+    {
+        next_task_id = IDLE_TASK_INDEX;
+    }
+
+    // no switch if no change
+    if (curr_task_id != next_task_id) 
+    {
+#if GIET_DEBUG_SWITCH
+_tty_get_lock( 0 );
+_puts("\n[GIET DEBUG] Context switch for processor ");
+_putd(_get_procid());
+_puts(" at cycle ");
+_putd(_get_proctime());
+_puts("\n");
+_puts(" - tasks        = ");
+_putd(tasks);
+_puts("\n");
+_puts(" - curr_task_id = ");
+_putd( curr_task_id );
+_puts("\n");
+_puts(" - next_task_id = ");
+_putd(next_task_id);
+_puts("\n");
+_tty_release_lock(  0 );
+#endif
+
+        unsigned int* curr_ctx_vaddr = &(psched->context[curr_task_id][0]);
+        unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]);
+        unsigned int procid = _get_procid();
+        unsigned int local_id = procid % NB_PROCS_MAX;
+        unsigned int cluster_id = procid / NB_PROCS_MAX;
+
+        // reset timer counter
+#if USE_XICU
+        _xcu_timer_reset_cpt(cluster_id, NB_PROCS_MAX + local_id);
+#else
+        _timer_reset_cpt(cluster_id, NB_PROCS_MAX + local_id); 
+#endif
+
+        // set current task index 
+        psched->current = next_task_id;
+
+        // makes context switch
+        _task_switch(curr_ctx_vaddr, next_ctx_vaddr);
+    }
+} //end _ctx_switch()
+
+/////////////////////////////////////////////////////////////////////////////////////
+// This function is executed as the"idle" task when no other task can be executed 
+/////////////////////////////////////////////////////////////////////////////////////
+void _idle_task() 
+{
+    unsigned int count = GIET_IDLE_TASK_PERIOD;
+    while(1)
+    {
+#if GIET_IDLE_TASK_VERBOSITY == 1
+        _tty_get_lock( 0 );
+        _puts("\n[GIET WARNING] Processor ");
+        _putd(_get_procid());
+        _puts(" idle at cycle ");
+        _putd(_get_proctime());
+        _puts("\n");
+        _tty_release_lock( 0 );
+#endif
+
+        asm volatile(
+                "move   $3,   %0              \n"
+                "_idle_task_loop:             \n"
+                "addi   $3,   $3,   -1        \n"
+                "bnez   $3,   _idle_task_loop \n"
+                "nop                          \n"
+                :
+                : "r"(count)
+                : "$3" ); 
+
+         count = GIET_IDLE_TASK_PERIOD;
+    }
+} // end ctx_idle()
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// The address of this functionis used to initialise the return address
+// in the "idle" task context.
+/////////////////////////////////////////////////////////////////////////////////
+void _ctx_eret() 
+{
+    asm volatile("eret");
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/ctx_handler.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/ctx_handler.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/ctx_handler.h	(revision 283)
@@ -0,0 +1,62 @@
+#ifndef _CTX_HANDLER_H
+#define _CTX_HANDLER_H
+
+#include <giet_config.h>
+
+/////////////////////////////////////////////////////////////////////////////////
+//    Definition of the scheduler structure
+/////////////////////////////////////////////////////////////////////////////////
+
+typedef struct static_scheduler_s 
+{
+    unsigned int context[15][64];      // at most 15 task contexts
+    unsigned int tasks;                // actual number of tasks
+    unsigned int current;              // current task index
+    unsigned int interrupt_vector[32]; // interrupt vector
+} static_scheduler_t;
+
+
+/////////////////////////////////////////////////////////////////////////////////
+//  "idle" task index definition
+/////////////////////////////////////////////////////////////////////////////////
+
+#define IDLE_TASK_INDEX        14
+
+/////////////////////////////////////////////////////////////////////////////////
+//    Definition of the task context slots indexes
+/////////////////////////////////////////////////////////////////////////////////
+
+#define CTX_SP_ID        29
+#define CTX_RA_ID        31
+
+#define CTX_EPC_ID       32  // Exception Program Counter (CP0)
+#define CTX_CR_ID        33  // Cause Register (CP0)
+#define CTX_SR_ID        34  // Status Register (CP0)
+#define CTX_BVAR_ID      35	 // Bad Virtual Address Register (CP0)
+
+#define CTX_PTAB_ID      36  // Page Table Virtual address
+#define CTX_LTID_ID      37  // Local  Task Index (in scheduler)
+#define CTX_VSID_ID      38  // Vspace Index     
+#define CTX_PTPR_ID      39  // Page Table Pointer Register (PADDR>>13)
+
+#define CTX_TTY_ID       40  // global TTY terminal  
+#define CTX_DMA_ID       41  // local DMA channel 
+#define CTX_NIC_ID       42  // global NIC channel 
+#define CTX_TIM_ID       43  // local TIMER channel
+#define CTX_HBA_ID       44  // global HBA channel
+#define CTX_CMA_ID       45  // global CMA channel 
+#define CTX_GTID_ID      46  // Global Task Index
+#define CTX_RUN_ID       47  // Boolean: task runable
+#define CTX_TRDID_ID     48  // Thread Index in vspace
+
+//////////////////////////////////////////////////////////////////////////////////
+//     Prototype of the context switch function
+//////////////////////////////////////////////////////////////////////////////////
+
+extern void _ctx_switch();
+extern void _ctx_eret();
+extern void _idle_task();
+
+extern static_scheduler_t _scheduler[];
+
+#endif
Index: /branch/giet_vm_ioc_drivers/giet_kernel/exc_handler.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/exc_handler.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/exc_handler.c	(revision 283)
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : exc_handler.c
+// Date     : 01/04/2012
+// Author   : alain greiner and joel porquet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The exc_handler.c and exc_handler.h files are part of the GIET nano-kernel.
+// They contains the exception handler code.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <exc_handler.h>
+#include <ctx_handler.h>
+#include <sys_handler.h>
+#include <tty_driver.h>
+#include <utils.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+// Prototypes of exception handlers.
+///////////////////////////////////////////////////////////////////////////////////
+
+static void _cause_ukn();
+static void _cause_adel();
+static void _cause_ades();
+static void _cause_ibe();
+static void _cause_dbe();
+static void _cause_bp();
+static void _cause_ri();
+static void _cause_cpu();
+static void _cause_ovf();
+
+extern void _int_handler();
+extern void _sys_handler();
+
+///////////////////////////////////////////////////////////////////////////////////
+// Initialize the exception vector indexed by the CR XCODE field
+///////////////////////////////////////////////////////////////////////////////////
+const _exc_func_t _cause_vector[16] = 
+{
+    &_int_handler,  /* 0000 : external interrupt */
+    &_cause_ukn,    /* 0001 : undefined exception */
+    &_cause_ukn,    /* 0010 : undefined exception */
+    &_cause_ukn,    /* 0011 : undefined exception */
+    &_cause_adel,   /* 0100 : illegal address read exception */
+    &_cause_ades,   /* 0101 : illegal address write exception */
+    &_cause_ibe,    /* 0110 : instruction bus error exception */
+    &_cause_dbe,    /* 0111 : data bus error exception */
+    &_sys_handler,  /* 1000 : system call */
+    &_cause_bp,     /* 1001 : breakpoint exception */
+    &_cause_ri,     /* 1010 : illegal codop exception */
+    &_cause_cpu,    /* 1011 : illegal coprocessor access */
+    &_cause_ovf,    /* 1100 : arithmetic overflow exception */
+    &_cause_ukn,    /* 1101 : undefined exception */
+    &_cause_ukn,    /* 1110 : undefined exception */
+    &_cause_ukn,    /* 1111 : undefined exception */
+};
+
+static const char * exc_type[] = 
+{
+    "strange unknown cause",
+    "illegal read address",
+    "illegal write address",
+    "inst bus error",
+    "data bus error",
+    "breakpoint",
+    "reserved instruction",
+    "illegal coproc access",
+    "arithmetic overflow",
+};
+
+
+static void _display_cause(unsigned int type) 
+{
+    _tty_get_lock( 0 );
+    _puts("\n[GIET] Exception for task ");
+    _putd(_get_context_slot(CTX_LTID_ID));
+    _puts(" on processor ");
+    _putd(_get_procid());
+    _puts(" at cycle ");
+    _putd(_get_proctime());
+    _puts("\n - type      : ");
+    _puts((char *) exc_type[type]);
+    _puts("\n - EPC       : ");
+    _putx(_get_epc());
+    _puts("\n - BVAR      : ");
+    _putx(_get_bvar());
+    _puts("\n");
+    _puts("...Task desactivated\n");
+    _tty_release_lock( 0 );
+
+    // goes to sleeping state
+    _set_context_slot(CTX_RUN_ID, 0);
+
+    // deschedule
+    _ctx_switch();
+}
+
+static void _cause_ukn()  { _display_cause(0); }
+static void _cause_adel() { _display_cause(1); }
+static void _cause_ades() { _display_cause(2); }
+static void _cause_ibe()  { _display_cause(3); }
+static void _cause_dbe()  { _display_cause(4); }
+static void _cause_bp()   { _display_cause(5); }
+static void _cause_ri()   { _display_cause(6); }
+static void _cause_cpu()  { _display_cause(7); }
+static void _cause_ovf()  { _display_cause(8); }
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/exc_handler.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/exc_handler.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/exc_handler.h	(revision 283)
@@ -0,0 +1,19 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : exc_handler.h
+// Date     : 01/04/2012
+// Author   : alain greiner and joel porquet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _EXCP_HANDLER_H
+#define _EXCP_HANDLER_H
+
+///////////////////////////////////////////////////////////////////////////////////
+// Exception Vector Table (indexed by cause register)
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef void (*_exc_func_t)(void);
+extern const _exc_func_t _cause_vector[16];
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/giet.s
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/giet.s	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/giet.s	(revision 283)
@@ -0,0 +1,167 @@
+/************************************************************************************
+* GIET: Interruption/Exception/Trap Handler for MIPS32 processor
+*
+* The base address of the segment containing this code MUST be 0x80000000, in
+* order to have the entry point at address 0x80000180!!! All messages are
+* printed on the TTY corresponding to the task&processor identifiers.
+*
+* It uses two arrays of functions:
+* - the _cause_vector[16] array defines the 16 causes to enter the GIET
+*   it is initialized in th exc_handler.c file
+* - the _syscall_vector[64] array defines the 64 system calls entry points
+*   it is initialised in the sys_handler.c file 
+***********************************************************************************/
+
+    .section .giet, "ax", @progbits
+    .space 0x180
+
+/*
+ * GIET Entry point (at address 0x80000180)
+ */
+
+    .func   _giet
+    .type   _giet, %function
+
+_giet:
+    mfc0    $27,    $13                 /* $27 <= Cause register */
+    la      $26,    _cause_vector       /* $26 <= _cause_vector */
+    andi    $27,    $27,    0x3c	    /* $27 <= XCODE*4 */
+    addu    $26,    $26,    $27		    /* $26 <= &_cause_vector[XCODE] */
+    lw      $26,    ($26)               /* $26 <=  _cause_vector[XCODE] */
+    jr      $26                         /* Jump indexed by XCODE */
+
+    .endfunc
+    .size _giet, .-_giet
+
+/*
+ * *** System Call Handler ***
+ *
+ * A system call is handled as a special function call.
+ *  - $2 contains the system call index (< 64).
+ *  - $3 is used to store the syscall address
+ *  - $4, $5, $6, $7 contain the arguments values.
+ *  - The return address (EPC) and the SR are saved in the stack.
+ *  - Interrupts are enabled before branching to the syscall.
+ *  - All syscalls must return to the syscall handler.
+ *  - $2, $3, $4, $5, $6, $7 as well as $26 & $27 can be modified.
+ *
+ * In case of undefined system call, an error message displays the value of EPC
+ * on the TTY corresponding to the processor, and the user program is killed.
+ */
+
+    .globl  _sys_handler
+    .func   _sys_handler
+    .type   _sys_handler, %function
+
+_sys_handler:
+    addiu   $29,    $29,    -24     /* 2 slots for SR&EPC, 4 slots for args passing */
+    mfc0    $26,    $12             /* load SR */
+    sw      $26,    16($29)         /* save it in the stack */
+    mfc0    $27,    $14             /* load EPC */
+    addiu   $27,    $27,    4       /* increment EPC for return address */
+    sw      $27,    20($29)         /* save it in the stack */
+
+    andi    $26,    $2,     0x3F    /* $26 <= syscall index (i < 64) */
+    sll     $26,    $26,    2       /* $26 <= index * 4 */
+    la      $27,    _syscall_vector /* $27 <= &_syscall_vector[0] */
+    addu    $27,    $27,    $26     /* $27 <= &_syscall_vector[i] */
+    lw      $3,     0($27)          /* $3  <= syscall address */
+
+    li      $27,    0xFFFFFFED      /* Mask for UM & EXL bits */
+    mfc0    $26,    $12             /* $26 <= SR */
+    and     $26,    $26,    $27     /* UM = 0 / EXL = 0 */
+    mtc0    $26,    $12             /* interrupt enabled */
+    jalr    $3                      /* jump to the proper syscall */
+    mtc0    $0,     $12             /* interrupt disbled */
+
+    lw      $26,    16($29)         /* load SR from stack */
+    mtc0    $26,    $12             /* restore SR */
+    lw      $26,    20($29)         /* load EPC from stack */
+    mtc0    $26,    $14             /* restore EPC */
+    addiu   $29,    $29,     24     /* restore stack pointer */
+    eret                            /* exit GIET */
+
+    .endfunc
+    .size _sys_handler, .-_sys_handler
+
+/*
+ * *** Interrupt Handler ***
+ *
+ * This simple interrupt handler cannot be interrupted.
+ *
+ * All non persistant registers, such as $1 to $15, and $24 to $25, as well as
+ * register $31 and EPC, are saved in the interrupted program stack, before
+ * calling the Interrupt Service Routine. These registers can be used by the
+ * ISR code.
+ */
+
+    .globl  _int_handler
+    .func   _int_handler
+    .type   _int_handler, %function
+
+_int_handler:
+    addiu   $29,    $29,    -25*4   /* stack space reservation (21 registers to
+                                       save and 4 free words to call function) */
+    .set noat
+    sw      $1,     4*4($29)        /* save $1 */
+    .set at
+    sw      $2,     5*4($29)        /* save $2 */
+    sw      $3,     6*4($29)        /* save $3 */
+    sw      $4,     7*4($29)        /* save $4 */
+    sw      $5,     8*4($29)        /* save $5 */
+    sw      $6,     9*4($29)        /* save $6 */
+    sw      $7,     10*4($29)       /* save $7 */
+    sw      $8,     11*4($29)       /* save $8 */
+    sw      $9,     12*4($29)       /* save $9 */
+    sw      $10,    13*4($29)       /* save $10 */
+    sw      $11,    14*4($29)       /* save $11 */
+    sw      $12,    15*4($29)       /* save $12 */
+    sw      $13,    16*4($29)       /* save $13 */
+    sw      $14,    17*4($29)       /* save $14 */
+    sw      $15,    18*4($29)       /* save $15 */
+    sw      $24,    19*4($29)       /* save $24 */
+    sw      $25,    20*4($29)       /* save $25 */
+    sw      $31,    21*4($29)       /* save $31 */
+    mflo    $26
+    sw      $26,    22*4($29)       /* save LO */
+    mfhi    $26
+    sw      $26,    23*4($29)       /* save HI */
+    mfc0    $27,    $14
+    sw      $27,    24*4($29)       /* save EPC */
+
+    la      $26,    _irq_demux
+    jalr    $26                     /* jump to a C function to find the proper ISR */
+
+restore:
+    .set noat
+    lw      $1,     4*4($29)        /* restore $1 */
+    .set at
+    lw      $2,     4*5($29)        /* restore $2 */
+    lw      $3,     4*6($29)        /* restore $3 */
+    lw      $4,     4*7($29)        /* restore $4 */
+    lw      $5,     4*8($29)        /* restore $5 */
+    lw      $6,     4*9($29)        /* restore $6 */
+    lw      $7,     4*10($29)       /* restore $7 */
+    lw      $8,     4*11($29)       /* restore $8 */
+    lw      $9,     4*12($29)       /* restore $9 */
+    lw      $10,    4*13($29)       /* restore $10 */
+    lw      $11,    4*14($29)       /* restore $11 */
+    lw      $12,    4*15($29)       /* restore $12 */
+    lw      $13,    4*16($29)       /* restore $13 */
+    lw      $14,    4*17($29)       /* restore $14 */
+    lw      $15,    4*18($29)       /* restore $15 */
+    lw      $24,    4*19($29)       /* restore $24 */
+    lw      $25,    4*20($29)       /* restore $25 */
+    lw      $31,    4*21($29)       /* restore $31 */
+    lw      $26,    4*22($29)
+    mtlo    $26                     /* restore LO */
+    lw      $26,    4*23($29)
+    mthi    $26                     /* restore HI */
+    lw      $27,    4*24($29)       /* return address (EPC) */
+    addiu   $29,    $29,    25*4    /* restore stack pointer */
+    mtc0    $27,    $14             /* restore EPC */
+    eret                            /* exit GIET */
+
+    .endfunc
+    .size _int_handler, .-_int_handler
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/irq_handler.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/irq_handler.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/irq_handler.c	(revision 283)
@@ -0,0 +1,274 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : irq_handler.c
+// Date     : 01/04/2012
+// Author   : alain greiner 
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The irq_handler.c and irq_handler.h files are part of the GIET-VM nano-kernel.
+// They contain the code of the _irq_demux() function that access the XICU or
+// ICU component (Interupt Controler Unit), and the various ISRs (Interrupt
+// Service Routine) associated to the peripherals. 
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+#include <irq_handler.h>
+#include <sys_handler.h>
+#include <ctx_handler.h>
+#include <tim_driver.h>
+#include <icu_driver.h>
+#include <xcu_driver.h>
+#include <tty_driver.h>
+#include <ioc_driver.h>
+#include <dma_driver.h>
+#include <mapping_info.h>
+#include <utils.h>
+
+#if !defined( USE_XICU )
+# error: You must define USE_XICU in the hard_config.h file
+#endif
+
+#if NB_TIM_CHANNELS
+extern volatile unsigned char _user_timer_event[X_SIZE*Y_SIZE*NB_TIM_CHANNELS] ;
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function uses the ICU or XICU component (Interrupt Controler Unit)
+// to get the interrupt vector entry. There is one ICU or XICU component per
+// cluster, and this component can support up to NB_PROCS_MAX output IRQs.
+// It returns the highest priority active interrupt index (smaller
+// indexes have the highest priority).
+// Any value larger than 31 means "no active interrupt", and no ISR is executed.
+//
+// There is one interrupt vector per processor (stored in the scheduler associated
+// to the processor. Each interrupt vector entry contains four bits fields:
+// - isr_id     bits[7:0]   : defines the type of ISR to be executed.
+// - type_id    bits[15:8]  : IRQ_TYPE_HWI / IRQ_TYPE_SWI / IRQ_TYPE_PTI
+// - channel_id bits[30:16] : defines the channel for multi-channels peripherals.
+// - valid      bit 31      : valid interrupt vector entry
+// If the peripheral is replicated in clusters (TIMER or DMA), the channel_id is 
+// a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id   
+///////////////////////////////////////////////////////////////////////////////////
+void _irq_demux() 
+{
+    unsigned int gpid       = _get_procid();
+    unsigned int cluster_id = gpid / NB_PROCS_MAX;
+    unsigned int local_id   = gpid % NB_PROCS_MAX;
+    unsigned int irq_id;
+    unsigned int ko;
+
+    // get the highest priority active IRQ index 
+
+    unsigned int icu_out_index = local_id * IRQ_PER_PROCESSOR;
+
+#if USE_XICU
+    ko = _xcu_get_index( cluster_id, icu_out_index, &irq_id );
+#else
+    ko = _icu_get_index( cluster_id, icu_out_index, &irq_id );
+#endif
+
+    if ( ko )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[GIET ERROR] Wrong _icu_read in _irq_demux()\n");
+        _tty_release_lock( 0 );
+    }
+
+    // do nothing if no interrupt active, or 
+    if (irq_id < 32) 
+    {
+        static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
+        unsigned int        entry      = psched->interrupt_vector[irq_id];
+        unsigned int        isr_id     = (entry    ) & 0x000000FF;
+        unsigned int        type_id    = (entry>> 8) & 0x000000FF;
+        unsigned int        channel_id = (entry>>16) & 0x00007FFF;
+
+        if(type_id == IRQ_TYPE_HWI)      // HWI
+        {
+            if      ( isr_id == ISR_SWITCH) _isr_switch(channel_id);
+            else if ( isr_id == ISR_IOC   ) _isr_ioc();
+            else if ( isr_id == ISR_TTY   ) _isr_tty(channel_id);
+            else if ( isr_id == ISR_TIMER ) _isr_timer(channel_id);
+            else if ( isr_id == ISR_WAKUP ) _isr_timer(channel_id);
+            else                            _isr_default( irq_id, isr_id, type_id );
+        }
+        else if(type_id == IRQ_TYPE_PTI) // PTI
+        {
+            if      ( isr_id == ISR_SWITCH) _isr_switch(irq_id);
+            else if ( isr_id == ISR_TIMER ) _isr_timer(irq_id);
+            else                            _isr_default( irq_id, isr_id, type_id );
+        }
+        else if(type_id == IRQ_TYPE_SWI) // SWI
+        {
+            if      ( isr_id == ISR_WAKUP ) return;
+            else                            _isr_default( irq_id, isr_id, type_id );
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// The default ISR is called when no specific ISR has been installed in the
+// interrupt vector. It simply displays an error message on kernel TTY[0].
+///////////////////////////////////////////////////////////////////////////////////
+void _isr_default( unsigned int irq_id,
+                   unsigned int isr_id,
+                   unsigned int type_id ) 
+{
+    _tty_get_lock( 0 );
+    _puts("\n[GIET ERROR] Undefined ISR index = ");
+    _putd( isr_id );
+    if(type_id == IRQ_TYPE_HWI) _puts(" / type = HWI ");
+    if(type_id == IRQ_TYPE_SWI) _puts(" / type = SWI ");
+    if(type_id == IRQ_TYPE_PTI) _puts(" / type = PTI ");
+    _puts(" / IRQ index = ");
+    _putd( irq_id );
+    _puts(" / processor = ");
+    _putd( _get_procid() );
+    _puts("\n");
+    _tty_release_lock( 0 );
+    _exit();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// This ISR is executed when a processor wakes up after a SWI interrup.
+///////////////////////////////////////////////////////////////////////////////////
+void _isr_wakup() 
+{
+    _tty_get_lock( 0 );
+    _puts("\n  Processor ");
+    _putd( _get_procid() );
+    _puts(" wake up\n");
+    _tty_release_lock( 0 );
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// There is only one IOC controler shared by all tasks. 
+// This ISR save the status, acknowledge the IRQ.
+// and activates the task waiting on IO transfer.
+//
+// TODO the _set_task_slot access should be replaced by an atomic LL/SC
+//      when the CTX_RUN bool will be replaced by a bit_vector. 
+///////////////////////////////////////////////////////////////////////////////////
+void _isr_ioc() 
+{
+    // save status in _ioc_status variable and reset IRQ 
+    if ( _ioc_get_status(0, &_ioc_status) ) return; 
+
+    // reactivate task waiting on IOC
+    unsigned int gpid = _ioc_gtid>>16;
+    unsigned int ltid = _ioc_gtid & 0xFFFF;
+
+    _set_task_slot( gpid,        // global processor index
+                    ltid,        // local task index (on processor)
+                    CTX_RUN_ID,  // CTX_RUN slot 
+                    1 );         // running
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// This ISR handles the IRQs generated by the "user" timers (the IRQs generated
+// by the "system" timers should be handled by the _isr_switch().
+// These timers are distributed in all clusters, and can be implemented
+// in a vci_multi_timer component, or in a vci_xicu component.
+// The timer_id argument is the user timer local index.
+//     timer_globa_id = cluster_id*(NB_TIM_CHANNELS) + timer_id 
+// The ISR acknowledges the IRQ and registers the event in the proper entry
+// of the _timer_event[] array, and a log message is displayed on kernel terminal.
+///////////////////////////////////////////////////////////////////////////////////
+void _isr_timer(unsigned int timer_id) 
+{
+    // compute cluster_id 
+    unsigned int cluster_id = _get_procid() / NB_PROCS_MAX;
+
+    // aknowledge IRQ 
+    if (_timer_reset_irq( cluster_id, timer_id)) 
+    {
+        _tty_get_lock( 0 );
+        _puts("[GIET ERROR] illegal timer index detected by _isr_timer\n");
+        _tty_release_lock( 0 );
+        return;
+    }
+
+#if NB_TIM_CHANNELS
+    // register the event
+    unsigned int timer_global_id = cluster_id * NB_TIM_CHANNELS + timer_id;
+    _user_timer_event[timer_global_id] = 1;
+#endif
+
+    // display a message on TTY 0 
+    _tty_get_lock( 0 );
+    _puts("\n[GIET] User Timer IRQ at cycle ");
+    _putd(_get_proctime());
+    _puts("\n - cluster_id = ");
+    _putd(cluster_id);
+    _puts("\n - timer_id   = ");
+    _putd(timer_id);
+    _puts("\n");
+    _tty_release_lock( 0 );
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// This ISR handles the IRQs generated by the multi_tty controler,
+// signaling that a character is available.
+// There is one single multi_tty component controling all TTYs, 
+// and the tty_id argument is the global TTY index.
+// There is one communication buffer _tty_buf[tty_id] per terminal.
+// The sychronisation variable _tty_full[tty_id], is set by the ISR,
+// and reset by the OS.
+// A character is lost if the buffer is full when the ISR is executed.
+///////////////////////////////////////////////////////////////////////////////////
+void _isr_tty(unsigned int tty_id) 
+{
+    // read character and reset IRQ in one read access
+    _tty_get_buf[tty_id] = _tty_read_data( tty_id ); 
+
+    // signals character available 
+    _tty_get_full[tty_id] = 1;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////
+// This ISR is in charge of context switch, and handle the IRQs generated by
+// the "system" timers. 
+// The IRQs can be generated by the MULTI_TIMER component or by the XICU component,
+// that are distributed in all clusters.
+// The ISR acknowledges the IRQ and calls the _ctx_switch() function.
+/////////////////////////////////////////////////////////////////////////////////////
+void _isr_switch( unsigned int timer_id) 
+{
+    // get cluster index 
+    unsigned int cluster_id = _get_procid() / NB_PROCS_MAX;
+
+    // acknowledge IRQ
+
+#if USE_XICU
+    if ( _xcu_timer_reset_irq( cluster_id, timer_id) ) 
+    {
+        _tty_get_lock( 0 );
+        _puts("[GIET ERROR] illegal proc index detected by _isr_switch\n");
+        _tty_release_lock( 0 );
+        return;
+    }
+#else
+    if (_timer_reset_irq(cluster_id, timer_id)) 
+    {
+        _tty_get_lock( 0 );
+        _puts("[GIET ERROR] illegal proc index detected by _isr_switch\n");
+        _tty_release_lock( 0 );
+        return;
+    }
+#endif
+
+    // performs the context switch
+    _ctx_switch();
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/irq_handler.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/irq_handler.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/irq_handler.h	(revision 283)
@@ -0,0 +1,39 @@
+#ifndef _IRQ_HANDLER_H
+#define _IRQ_HANDLER_H
+
+enum isr_type_t
+{
+    ISR_DEFAULT = 0,
+    ISR_SWITCH  = 1,
+    ISR_TTY     = 2,
+    ISR_DMA     = 3,
+    ISR_IOC     = 4,
+    ISR_TIMER   = 5,
+    ISR_WAKUP   = 6,
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Prototypes of the Interrupt Service Routines (ISRs) supported by the GIET.
+///////////////////////////////////////////////////////////////////////////////
+
+extern void _irq_demux();
+
+extern void _isr_default();
+extern void _isr_ioc();
+extern void _isr_timer(unsigned int channel);
+extern void _isr_dma(unsigned int channel);
+extern void _isr_tty(unsigned int channel);
+extern void _isr_switch();
+extern void _isr_wakup();
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/kernel.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/kernel.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/kernel.ld	(revision 283)
@@ -0,0 +1,52 @@
+
+/******************************************************************************/
+/* Definition of the base addresses for all vsegs used by the GIET_VM         */
+/******************************************************************************/
+
+INCLUDE giet_vsegs.ld
+
+/******************************************************************************/
+/* Grouping sections into virtual segments for system code and data           */
+/******************************************************************************/
+
+SECTIONS
+{
+    . = seg_kernel_code_base;
+    seg_kernel_code : 
+    {
+        *(.giet)
+        *(.text)
+    }
+
+    . = seg_kernel_data_base;
+    seg_kernel_data : 
+    {
+        *(.iommu)
+        *(.fatdata)
+        *(.descriptor)
+        *(.kdata)
+        *(.rodata)
+        *(.rodata.*)
+        *(.data)
+        *(.lit8)
+        *(.lit4)
+        *(.sdata)
+        *(.bss)
+        *(COMMON)
+        *(.sbss)
+        *(.scommon)
+    }
+
+    . = seg_kernel_uncdata_base;
+    seg_kernel_uncdata : 
+    {
+        *(.unckdata)
+    }
+
+    . = seg_kernel_init_base;
+    seg_kernel_init : 
+    {
+        *(.kinit)
+    }
+}
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/kernel_init.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/kernel_init.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/kernel_init.c	(revision 283)
@@ -0,0 +1,444 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : kernel_init.c
+// Date     : 26/05/2012
+// Authors  : alain greiner & mohamed karaoui
+// Copyright (c) UPMC-LIP6
+////////////////////////////////////////////////////////////////////////////////////
+// The kernel_init.c file is part of the GIET-VM nano-kernel.
+//
+// This nano-kernel has been written for the MIPS32 processor.
+// The virtual adresses are on 32 bits and use the (unsigned int) type, but the 
+// physicals addresses can have up to 40 bits, and use the  (unsigned long long) type.
+// It natively supports clusterised shared mmemory multi-processors architectures, 
+// where each processor is identified by a composite index (cluster_xy, local_id),
+// and where there is one physical memory bank per cluster.
+//
+// This file contains the _kernel_init() function, that performs the second 
+// phase of system initialisation.  The three significant actions are:
+// 1) processor 0 makes peripherals and system FAT initialisation.
+// 2) processor 0 awake all other processors by an IPI.
+// 3) all processors running in parallel perform register initialisation,
+//    from their private scheduler, and jump to user code.
+////////////////////////////////////////////////////////////////////////////////////
+
+#include <giet_config.h>
+
+// kernel libraries
+#include <utils.h>
+#include <fat32.h>
+
+//for peripheral initialisation
+#include <dma_driver.h>
+#include <fbf_driver.h>
+#include <tty_driver.h>
+#include <icu_driver.h>
+#include <xcu_driver.h>
+#include <ioc_driver.h>
+#include <mmc_driver.h>
+#include <mwr_driver.h>
+#include <nic_driver.h>
+#include <tim_driver.h>
+
+#include <ctx_handler.h>
+#include <irq_handler.h>
+
+#include <mapping_info.h>
+#include <mips32_registers.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+// array of pointers on the page tables (virtual addresses)
+///////////////////////////////////////////////////////////////////////////////////
+
+__attribute__((section (".kdata"))) 
+unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];    // virtual addresses
+
+__attribute__((section (".kdata")))        
+unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX];    // physical addresses >> 13
+
+///////////////////////////////////////////////////////////////////////////////////
+// array of pointers on the schedulers (physical addresses)
+///////////////////////////////////////////////////////////////////////////////////
+
+__attribute__((section (".kdata"))) 
+static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)];   // virtual addresses
+
+////////////////////////////////////////////////////////////////////////////////////
+// staks for the "idle" tasks (256 bytes for each processor)
+////////////////////////////////////////////////////////////////////////////////////
+
+__attribute__((section (".kdata"))) 
+unsigned int _idle_stack[X_SIZE*Y_SIZE * NB_PROCS_MAX * 128]; 
+
+////////////////////////////////////////////////////////////////////////////////////
+// This function is the entry point in kernel for all processors.
+// It is executed in parallel by all procesors, and completes the system 
+// initialisation that has been started by processor 0 in the boot_init() function.
+//
+// This kernel code makes the following assuptions, regarding the work bone 
+// by the boot code:
+//
+// 1) The page tables associated to the various vspaces have been build
+//    in physical memory, and can be used by the kernel code.
+//
+// 2) All schedulers (this include all task contexts) have been initialised, 
+//    Both the virtual and the physical base addresses of the page tables
+//    are available in the CTX_PTAB and CTX_PTPR slots.
+//
+// 3) The CP0_SCHED register of each processor contains a pointer on its 
+//    private scheduler (virtual address).
+//
+// 4) The CP2_PTPR register of each processor contains a pointer on 
+//    the vspace_0 page table (physical address>>13). 
+//
+// 5) For all processors, the MMU is activated (CP2_MODE contains 0xF).
+// 
+// This code must be loaded in .kinit section, in order to control seg_kinit_base,
+// as this address is used by the boot code to jump into kernel code.
+////////////////////////////////////////////////////////////////////////////////////
+// Each processor performs the following actions:
+// 1/ contribute to _schedulers_paddr[] array initialisation.
+// 2/ contribute to _ptabs_paddr[] and _ptabs_vaddr arrays initialisation 
+// 3/ compute and set the ICU mask for its private ICU channel
+// 4/ initialise its private TICK timer (if tasks > 0)
+// 5/ initialise the "idle" task context in its private scheduler
+// 6/ initialise the SP, SR, PTPR, EPC registers
+// 7/ jump to the user code with an eret. 
+////////////////////////////////////////////////////////////////////////////////////
+__attribute__((section (".kinit"))) void kernel_parallel_init() 
+{
+    unsigned int global_pid = _get_procid();
+    unsigned int cluster_xy = global_pid / NB_PROCS_MAX;
+    unsigned int local_pid  = global_pid % NB_PROCS_MAX;
+
+#if 0
+////////////// Debug : we can kill all processors but one
+if ( global_pid != 0 ) 
+{
+    _tty_get_lock( 0 );
+    _puts("\n[GIET] Processor[");
+    _putd( cluster_xy >> Y_WIDTH );
+    _puts(",");
+    _putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+    _puts(",");
+    _putd( local_pid );
+    _puts("] suicide...\n");
+    _tty_release_lock( 0 );
+    _exit();
+}
+#endif
+
+    // Step 1 : each processor get its scheduler virtual address
+    //          and contribute to initialise the _schedulers[] array
+
+    static_scheduler_t* psched     = (static_scheduler_t*)_get_sched();
+    unsigned int        tasks      = psched->tasks;
+
+    _schedulers[global_pid] = psched;
+
+#if GIET_DEBUG_INIT
+_tty_get_lock( 0 );
+_puts("\n[GIET DEBUG] Parallel init : step 1 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("]\n - scheduler vbase = ");
+_putx((unsigned int) psched);
+_puts("\n - tasks           = ");
+_putd(tasks);
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // step 2 : each processor that is allocated at least one task
+    //          completes its private scheduler initialisation, and
+    //          contribute to _ptabs_vaddr[] and _ptabs_ptprs[] arrays initialisation.
+    //          - set the CTX_RA slot vith the virtual address
+    //            of the _ctx_eret() function (for context switch).
+    //          - set the CTX_EPC slot that must contain the task
+    //            entry point, and contain only the address of the
+    //            memory location containing this entry point.
+
+    unsigned int ltid;
+
+    // loop on all allocated tasks
+    for (ltid = 0; ltid < tasks; ltid++) 
+    {
+        unsigned int vsid = _get_task_slot( global_pid, ltid , CTX_VSID_ID ); 
+        unsigned int ptab = _get_task_slot( global_pid, ltid , CTX_PTAB_ID ); 
+        unsigned int ptpr = _get_task_slot( global_pid, ltid , CTX_PTPR_ID ); 
+
+        _ptabs_vaddr[vsid] = ptab;
+        _ptabs_ptprs[vsid] = ptpr;
+
+        unsigned int ctx_ra = (unsigned int)(&_ctx_eret);
+        _set_task_slot( global_pid, ltid, CTX_RA_ID, ctx_ra );
+
+        unsigned int* ptr = (unsigned int*)_get_task_slot( global_pid, ltid, CTX_EPC_ID );
+        _set_task_slot( global_pid, ltid, CTX_EPC_ID, *ptr );
+
+#if GIET_DEBUG_INIT
+_tty_get_lock( 0 );
+_puts("\n[GIET DEBUG] Parallel init : step 2 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("] / task ");
+_putd( ltid );
+_puts("\n - ctx_vsid  = ");
+_putd( _get_task_slot( global_pid, ltid, CTX_VSID_ID ) );
+_puts("\n - ctx_ptpr  = ");
+_putx( _get_task_slot( global_pid, ltid, CTX_PTPR_ID ) );
+_puts("\n - ctx_ptab  = ");
+_putx( _get_task_slot( global_pid, ltid, CTX_PTAB_ID ) );
+_puts("\n - ctx_ltid  = ");
+_putd( _get_task_slot( global_pid, ltid, CTX_LTID_ID ) );
+_puts("\n - ctx_epc   = ");
+_putx( _get_task_slot( global_pid, ltid, CTX_EPC_ID ) );
+_puts("\n - ctx_ra    = ");
+_putx( _get_task_slot( global_pid, ltid, CTX_RA_ID ) );
+_puts("\n - ctx_gtid  = ");
+_putd( _get_task_slot( global_pid, ltid, CTX_GTID_ID ) );
+_puts("\n - ctx_tty   = ");
+_putd( _get_task_slot( global_pid, ltid, CTX_TTY_ID ) );
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    }
+
+    // step 3 : compute and set ICU or XICU masks
+    //          there is at most 32 interrupts per processor
+
+    unsigned int isr_switch_index = 0xFFFFFFFF;
+    unsigned int irq_id;            // IN_IRQ index
+    unsigned int hwi_mask = 0;
+    unsigned int swi_mask = 0;
+    unsigned int pti_mask = 0;
+
+    for (irq_id = 0; irq_id < 32; irq_id++) 
+    {
+        unsigned int entry = psched->interrupt_vector[irq_id];
+        unsigned int isr   = (entry & 0x000000FF);
+        unsigned int type  = (entry & 0x0000FF00) >> 8;
+        unsigned int valid = (entry & 0x80000000);
+
+        if      ((type == IRQ_TYPE_HWI) && valid ) hwi_mask = hwi_mask | (1<<irq_id);
+        else if ((type == IRQ_TYPE_SWI) && valid ) swi_mask = swi_mask | (1<<irq_id);
+        else if ((type == IRQ_TYPE_PTI) && valid ) pti_mask = pti_mask | (1<<irq_id);
+        else if ( valid )
+        {
+            _puts("\n[GIET ERROR] _kernel_parallel_start() : illegal IRQ type\n");
+            _puts(" irq_id = ");
+            _putx( irq_id );
+            _puts(" / entry = ");
+            _putx( entry );
+            _puts("\n");
+            _exit();
+        }
+        if (isr == ISR_SWITCH) isr_switch_index = irq_id;
+    }
+
+#if GIET_DEBUG_INIT
+_tty_get_lock( 0 );
+_puts("\n[GIET DEBUG] Parallel init : step 3 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("]\n - ICU HWI_MASK = ");
+_putx(hwi_mask);
+_puts("\n - ICU SWI_MASK = ");
+_putx(swi_mask);
+_puts("\n - ICU PTI_MASK = ");
+_putx(pti_mask);
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // GIET-VM constraint : only one IRQ type per irq_id 
+    if ( hwi_mask & swi_mask & pti_mask )
+    {
+        _puts("[GIET ERROR] _kernel_parallel_start : conflicting IRQs\n");
+        _exit();
+    }
+
+
+    // The ICU output index is computed as the local processor id multiplied by
+    // the number of ICU outputs connected to each processor.
+    int icu_out_index = local_pid * IRQ_PER_PROCESSOR; 
+
+#if USE_XICU
+    _xcu_set_mask(cluster_xy, icu_out_index, hwi_mask, IRQ_TYPE_HWI); // set HWI_MASK
+    _xcu_set_mask(cluster_xy, icu_out_index, swi_mask, IRQ_TYPE_SWI); // set SWI_MASK
+    _xcu_set_mask(cluster_xy, icu_out_index, pti_mask, IRQ_TYPE_PTI); // set PTI_MASK
+#else
+    _icu_set_mask(cluster_xy, icu_out_index, (hwi_mask | pti_mask | swi_mask) );   
+#endif
+
+    // step 4 : start TICK timer if at least one task
+    if (tasks > 0) 
+    {
+        // one ISR_SWITCH must be defined for each proc
+        if (isr_switch_index == 0xFFFFFFFF) 
+        {
+            _tty_get_lock( 0 );
+            _puts("\n[GIET ERROR] ISR_SWITCH not found for processor ");
+            _putx(global_pid);
+            _puts("\n");
+            _tty_release_lock( 0 );
+            _exit();
+        }
+
+        // the ISR_SWITCH irq index must be NB_PROCS_MAX + local_pid because
+        // the first NB_PROCS_MAX irqs are used by the WAKEUP ones
+        if (isr_switch_index != (NB_PROCS_MAX + local_pid))
+        {
+            _tty_get_lock( 0 );
+            _puts("\n[GIET ERROR] ISR_SWITCH wrong index for processor ");
+            _putx(global_pid);
+            _puts("\n. It should be NB_PROCS_MAX + local_pid =");
+            _putd(NB_PROCS_MAX + local_pid);
+            _puts("\n");
+            _tty_release_lock( 0 );
+            _exit();
+        }
+
+        // start system timer
+        unsigned int ko;
+#if USE_XICU
+        ko = _xcu_timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE ); 
+#else
+        ko = _timer_start( cluster_xy, isr_switch_index, GIET_TICK_VALUE ); 
+#endif
+        if ( ko )
+        {
+            _tty_get_lock( 0 );
+            _puts("\n[GIET ERROR] cannot start timer for processor ");
+            _putd(local_pid);
+            _puts("\n");
+            _tty_release_lock( 0 );
+            _exit();
+        }
+    } 
+
+#if GIET_DEBUG_INIT
+_tty_get_lock( 0 );
+_puts("\n[GIET DEBUG] Parallel init : step 4 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("]");
+if ( tasks > 1 ) _puts("\n  context switch activated\n");
+else             _puts("\n  context switch  not activated\n");
+_tty_release_lock( 0 );
+#endif
+
+    // step 5 : each processor updates the idle_task context:
+    //          (only CTX_SP, CTX_RA, CTX_EPC).
+    //          The stack size is 256 bytes, reserved in seg_kdata.
+    //          The PTPR register, the CTX_PTPR and CTX_PTAB slots 
+    //          have been initialised in boot code.
+
+    unsigned int stack = (unsigned int)_idle_stack + ((global_pid + 1)<<9);
+
+    _set_task_slot( global_pid, IDLE_TASK_INDEX, CTX_SP_ID,  stack);
+    _set_task_slot( global_pid, IDLE_TASK_INDEX, CTX_RA_ID,  (unsigned int) &_ctx_eret);
+    _set_task_slot( global_pid, IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_idle_task);
+
+#if GIET_DEBUG_INIT
+_tty_get_lock( 0 );
+_puts("\n[GIET DEBUG] Parallel init : step 5 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("] : idle task context set\n");
+_tty_release_lock( 0 );
+#endif
+
+    // step 6 : each processor initialises SP, SR, PTPR, EPC, registers
+    //          with the values corresponding to the first allocated task,
+    //          or to the idle_task if there is no task allocated.
+
+    ltid = 0;
+
+    if (tasks == 0) 
+    {
+        ltid = IDLE_TASK_INDEX;
+
+        _tty_get_lock( 0 );
+        _puts("\n[GIET WARNING] No task allocated to processor ");
+        _putx(global_pid);
+        _puts(" => idle\n");
+        _tty_release_lock ( 0 );
+    }
+
+    unsigned int sp_value   = _get_task_slot(global_pid, ltid, CTX_SP_ID);
+    unsigned int sr_value   = _get_task_slot(global_pid, ltid, CTX_SR_ID);
+    unsigned int ptpr_value = _get_task_slot(global_pid, ltid, CTX_PTPR_ID);
+    unsigned int epc_value  = _get_task_slot(global_pid, ltid, CTX_EPC_ID);
+
+#if GIET_DEBUG_INIT
+_tty_get_lock( 0 );
+_puts("\n[GIET DEBUG] Parallel init : step 6 for processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("]\n - sp   = ");
+_putx(sp_value);
+_puts("\n - sr   = ");
+_putx(sr_value);
+_puts("\n - ptpr = ");
+_putx(ptpr_value);
+_puts("\n - epc  = ");
+_putx(epc_value);
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+_tty_get_lock( 0 );
+_puts("\n[GIET] Processor[");
+_putd( cluster_xy >> Y_WIDTH );
+_puts(",");
+_putd( cluster_xy & ((1<<Y_WIDTH)-1) );
+_puts(",");
+_putd( local_pid );
+_puts("] completes kernel init at cycle ");
+_putd( _get_proctime() );
+_puts(" / task_entry_point = ");
+_putx( epc_value );
+_puts("\n");
+_tty_release_lock( 0 );
+
+    // Step 7 : set  registers and jump to user code
+    asm volatile (
+            "move    $29,       %0    \n"        /* SP <= ctx[CTX_SP_ID] */
+            "mtc0    %1,        $12   \n"        /* SR <= ctx[CTX_SR_ID] */
+            "mtc2    %2,        $0    \n"        /* PTPR <= ctx[CTX_PTPR_ID] */
+            "mtc0    %3,        $14   \n"        /* EPC <= ctx[CTX_EPC_ID] */
+            "eret                     \n"        /* jump to user code */
+            "nop                      \n"
+            :
+            : "r" (sp_value), "r" (sr_value), "r" (ptpr_value), "r" (epc_value));
+
+} // end kernel_parallel_init()
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/switch.s
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/switch.s	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/switch.s	(revision 283)
@@ -0,0 +1,136 @@
+/******************************************************************************
+* This function receives two arguments that are the current task context 
+* (virtual) addresses and the next task context (virtual) address.
+*
+* TODO (AG) Il semble possible de limiter le nombre de registres Ã  sauver:
+* - s0 Ã  s8 ($16 Ã  $23 + $30)
+* - sp ($29)
+* - ra ($31)
+* - hi et lo
+* - sr
+* - epc
+* - ptpr
+******************************************************************************/
+
+    .globl  _task_switch
+    .func   _task_switch
+    .type   _task_switch, %function
+
+_task_switch:
+
+    /* enter critical section */
+    li      $2,     0xFFFFFFFE  
+    mfc0    $3,     $12        
+    and     $3,     $3, $2    
+    mtc0    $3,     $12    
+
+    /* save _current task context */
+    add     $27,    $4,     $0  /* $27 <= &context[curr_task_id] */
+
+    .set noat
+    sw      $1,     1*4($27)    /* ctx[1] <= $1 */
+    .set at
+    sw      $2,     2*4($27)    /* ctx[2] <= $2 */
+    sw      $3,     3*4($27)    /* ctx[3] <= $3 */
+    sw      $4,     4*4($27)    /* ctx[4] <= $4 */
+    sw      $5,     5*4($27)    /* ctx[5] <= $5 */
+    sw      $6,     6*4($27)    /* ctx[6] <= $6 */
+    sw      $7,     7*4($27)    /* ctx[7] <= $7 */
+    sw      $8,     8*4($27)    /* ctx[8] <= $8 */
+    sw      $9,     9*4($27)    /* ctx[9] <= $9 */
+    sw      $10,    10*4($27)   /* ctx[10] <= $10 */
+    sw      $11,    11*4($27)   /* ctx[11] <= $11 */
+    sw      $12,    12*4($27)   /* ctx[12] <= $12 */
+    sw      $13,    13*4($27)   /* ctx[13] <= $13 */
+    sw      $14,    14*4($27)   /* ctx[14] <= $14 */
+    sw      $15,    15*4($27)   /* ctx[15] <= $15 */
+    sw      $16,    16*4($27)   /* ctx[16] <= $16 */
+    sw      $17,    17*4($27)   /* ctx[17] <= $17 */
+    sw      $18,    18*4($27)   /* ctx[18] <= $18 */
+    sw      $19,    19*4($27)   /* ctx[19] <= $19 */
+    sw      $20,    20*4($27)   /* ctx[20] <= $20 */
+    sw      $21,    21*4($27)   /* ctx[21] <= $21 */
+    sw      $22,    22*4($27)   /* ctx[22] <= $22 */
+    sw      $23,    23*4($27)   /* ctx[23] <= $23 */
+    sw      $24,    24*4($27)   /* ctx[24] <= $24 */
+    sw      $25,    25*4($27)   /* ctx[25] <= $25 */
+    mflo    $26
+    sw      $26,    26*4($27)   /* ctx[26] <= LO  */
+    mfhi    $26
+    sw      $26,    27*4($27)   /* ctx[27] <= H1  */
+    sw      $28,    28*4($27)   /* ctx[28] <= $28 */
+    sw      $29,    29*4($27)   /* ctx[29] <= $29 */
+    sw      $30,    30*4($27)   /* ctx[30] <= $30 */
+    sw      $31,    31*4($27)   /* ctx[31] <= $31 */
+    mfc0    $26,    $14
+    sw      $26,    32*4($27)   /* ctx[32] <= EPC */
+    mfc0    $26,    $13
+    sw      $26,    33*4($27)   /* ctx[33] <= CR  */
+    mfc0    $26,    $12
+    sw      $26,    34*4($27)   /* ctx[34] <= SR  */
+    mfc0    $26,    $8
+    sw      $26,    35*4($27)   /* ctx[34] <= BVAR */
+    mfc2    $26,    $0
+    sw      $26,    39*4($27)   /* ctx[35] <= PTPR */
+
+    /* restore next task context */
+    add     $27,    $5,     $0  /* $27<= &context[next_task_id] */
+
+    .set noat
+    lw      $1,     1*4($27)    /* restore $1 */
+    .set at
+    lw      $2,     2*4($27)    /* restore $2 */
+    lw      $3,     3*4($27)    /* restore $3 */
+    lw      $4,     4*4($27)    /* restore $4 */
+    lw      $5,     5*4($27)    /* restore $5 */
+    lw      $6,     6*4($27)    /* restore $6 */
+    lw      $7,     7*4($27)    /* restore $7 */
+    lw      $8,     8*4($27)    /* restore $8 */
+    lw      $9,     9*4($27)    /* restore $9 */
+    lw      $10,    10*4($27)   /* restore $10 */
+    lw      $11,    11*4($27)   /* restore $11 */
+    lw      $12,    12*4($27)   /* restore $12 */
+    lw      $13,    13*4($27)   /* restore $13 */
+    lw      $14,    14*4($27)   /* restore $14 */
+    lw      $15,    15*4($27)   /* restore $15 */
+    lw      $16,    16*4($27)   /* restore $16 */
+    lw      $17,    17*4($27)   /* restore $17 */
+    lw      $18,    18*4($27)   /* restore $18 */
+    lw      $19,    19*4($27)   /* restore $19 */
+    lw      $20,    20*4($27)   /* restore $20 */
+    lw      $21,    21*4($27)   /* restore $21 */
+    lw      $22,    22*4($27)   /* restore $22 */
+    lw      $23,    23*4($27)   /* restore $23 */
+    lw      $24,    24*4($27)   /* restore $24 */
+    lw      $25,    25*4($27)   /* restore $25 */
+    lw      $26,    26*4($27)
+    mtlo    $26                 /* restore LO */
+    lw      $26,    27*4($27)
+    mthi    $26                 /* restore HI */
+    lw      $28,    28*4($27)   /* restore $28 */
+    lw      $29,    29*4($27)   /* restore $29 */
+    lw      $30,    30*4($27)   /* restore $30 */
+    lw      $31,    31*4($27)   /* restore $31 */
+    lw      $26,    32*4($27)
+    mtc0    $26,    $14         /* restore EPC */
+    lw      $26,    33*4($27)
+    mtc0    $26,    $13         /* restore CR */
+    lw      $26,    34*4($27)
+    mtc0    $26,    $12         /* restore SR */
+    lw      $26,    35*4($27)
+    mtc0    $26,    $8          /* restore BVAR */
+    lw      $26,    39*4($27)
+    mtc2    $26,    $0          /* restore PTPR */
+
+    /* exit critical section */
+    li      $2,     0x00000001  
+    mfc0    $3,     $12        
+    or      $3,     $3, $2    
+    mtc0    $3,     $12    
+
+    /* returns to caller */
+    jr      $31 
+
+    .endfunc
+    .size _task_switch, .-_task_switch
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/sys_handler.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/sys_handler.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/sys_handler.c	(revision 283)
@@ -0,0 +1,324 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : sys_handler.c
+// Date     : 01/04/2012
+// Author   : alain greiner and joel porquet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The sys_handler.c and sys_handler.h files are part of the GIET-VM nano-kernel.
+// It define the syscall_vector[] (at the end of this file), as well as the 
+// associated syscall handlers that are not related to peripherals.
+// The syscall handlers for peripherals are defined in the drivers.c file.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <sys_handler.h>
+#include <tty_driver.h>
+#include <tim_driver.h>
+#include <ioc_driver.h>
+#include <nic_driver.h>
+#include <fbf_driver.h>
+#include <ctx_handler.h>
+#include <fat32.h>
+#include <utils.h>
+#include <giet_config.h>
+#include <mapping_info.h>
+
+////////////////////////////////////////////////////////////////////////////
+//    Initialize the syscall vector with syscall handlers
+// Note: This array must be synchronised with the define in file stdio.h
+////////////////////////////////////////////////////////////////////////////
+const void * _syscall_vector[64] = 
+{
+    &_get_procid,          /* 0x00 */
+    &_get_proctime,        /* 0x01 */
+    &_tty_write,           /* 0x02 */
+    &_tty_read,            /* 0x03 */
+    &_timer_start,         /* 0x04 */
+    &_timer_stop,          /* 0x05 */
+    &_sys_ukn,             /* 0x06 */
+    &_sys_ukn,             /* 0x07 */
+    &_heap_info,           /* 0x08 */
+    &_local_task_id,       /* 0x09 */
+    &_global_task_id,      /* 0x0A */ 
+    &_fb_cma_init,         /* 0x0B */
+    &_fb_cma_write,        /* 0x0C */
+    &_fb_cma_stop,         /* 0x0D */
+    &_task_exit,           /* 0x0E */
+    &_procs_number,        /* 0x0F */
+
+    &_fb_sync_write,       /* 0x10 */
+    &_fb_sync_read,        /* 0x11 */
+    &_thread_id,           /* 0x12 */
+    &_tty_get_release_lock,/* 0x13 */
+    &_sys_ukn,             /* 0x14 */
+    &_sys_ukn,             /* 0x15 */ 
+    &_sys_ukn,             /* 0x16 */
+    &_sys_ukn,             /* 0x17 */
+    &_sys_ukn,             /* 0x18 */   
+    &_ctx_switch,          /* 0x19 */
+    &_vobj_get_vbase,      /* 0x1A */
+    &_sys_ukn,             /* 0x1B */
+    &_nic_cma_start,       /* 0x1C */
+    &_nic_cma_stop,        /* 0x1D */
+    &_nic_sync_read,       /* 0x1E */
+    &_nic_sync_write,      /* 0x1F */
+
+    &_fat_user_open,       /* 0x20 */
+    &_fat_user_read,       /* 0x21 */
+    &_fat_user_write,      /* 0x22 */
+    &_fat_user_lseek,      /* 0x23 */
+    &_fat_fstat,           /* 0x24 */
+    &_fat_close,           /* 0x25 */
+    &_sys_ukn,             /* 0x26 */
+    &_sys_ukn,             /* 0x27 */
+    &_sys_ukn,             /* 0x28 */
+    &_sys_ukn,             /* 0x29 */
+    &_sys_ukn,             /* 0x2A */
+    &_sys_ukn,             /* 0x2B */
+    &_sys_ukn,             /* 0x2C */
+    &_sys_ukn,             /* 0x2D */
+    &_sys_ukn,             /* 0x2E */
+    &_sys_ukn,             /* 0x2F */
+
+    &_sys_ukn,             /* 0x30 */
+    &_sys_ukn,             /* 0x31 */
+    &_sys_ukn,             /* 0x32 */
+    &_sys_ukn,             /* 0x33 */
+    &_sys_ukn,             /* 0x34 */
+    &_sys_ukn,             /* 0x35 */ 
+    &_sys_ukn,             /* 0x36 */
+    &_sys_ukn,             /* 0x37 */
+    &_sys_ukn,             /* 0x38 */   
+    &_sys_ukn,             /* 0x39 */
+    &_sys_ukn,             /* 0x3A */
+    &_sys_ukn,             /* 0x3B */
+    &_sys_ukn,             /* 0x3C */
+    &_sys_ukn,             /* 0x3D */
+    &_sys_ukn,             /* 0x3E */
+    &_sys_ukn,             /* 0x3F */
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// function executed in case of undefined syscall
+//////////////////////////////////////////////////////////////////////////////
+void _sys_ukn() 
+{
+    unsigned int epc;
+    asm volatile("mfc0 %0, $14" : "=r" (epc));
+
+    _tty_get_lock( 0 );
+    _puts("\n\n!!! Undefined System Call !!!\n");
+    _puts("\nEPC = ");
+    _putx(epc);
+    _tty_release_lock( 0 );
+    _exit();
+}
+
+////////////////////////////////////////////////////////////////////////////
+// _exit()
+// Task suicide... after printing a death message.
+////////////////////////////////////////////////////////////////////////////
+void _task_exit() 
+{
+    unsigned int date    = _get_proctime();
+    unsigned int proc_id = _get_procid();
+    unsigned int task_id = _get_context_slot(CTX_LTID_ID);
+
+    // print death message
+    _tty_get_lock( 0 );
+    _puts("\n[GIET] Exit task ");
+    _putd(task_id);
+    _puts(" on processor ");
+    _putd(proc_id);
+    _puts(" at cycle ");
+    _putd(date);
+    _puts("\n\n");
+    _tty_release_lock( 0 );
+
+    // goes to sleeping state
+    _set_context_slot(CTX_RUN_ID, 0);
+
+    // deschedule
+    _context_switch();
+} 
+
+//////////////////////////////////////////////////////////////////////////////
+// _procnumber()
+// returns in buffer argument the number of processors in the cluster
+// specified by the cluster_id argument.
+//////////////////////////////////////////////////////////////////////////////
+unsigned int _procs_number(unsigned int  cluster_id, 
+                           unsigned int* buffer) 
+{
+    mapping_header_t * header  = (mapping_header_t *) &seg_boot_mapping_base;
+    mapping_cluster_t * cluster = _get_cluster_base(header);
+
+    if ( cluster_id < X_SIZE * Y_SIZE ) 
+    {
+        *buffer = cluster[cluster_id].procs;
+        return 0;
+    }
+    else 
+    {
+        return 1;
+    }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// _local_task_id()
+// Returns current task local index.
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _local_task_id()
+{
+    return _get_context_slot(CTX_LTID_ID);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// _global_task_id()
+// Returns current task global index.
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _global_task_id()
+{
+    return _get_context_slot(CTX_GTID_ID);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// _thread_id()
+// Returns current thread index.
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _thread_id()
+{
+    return _get_context_slot(CTX_TRDID_ID);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// _tty_get_release_lock(int val)
+// Get or release the hardware TTY lock depending on val (0: get,1: release)
+/////////////////////////////////////////////////////////////////////////////
+int _tty_get_release_lock(unsigned int val)
+{
+    unsigned int channel = _get_context_slot(CTX_TTY_ID);
+
+    if      ( val == 0 ) _tty_get_lock(channel);
+    else if ( val == 1 ) _tty_release_lock(channel);
+    else return -1; // Wrong action
+
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// _get_vobj()
+// This function writes in res_vobj a pointer on a vobj 
+// identified by the (vspace_name / vobj_name ) couple.
+// The vobj_type argument is here only for the purpose of checking .
+// returns 0: success, else: failed.
+/////////////////////////////////////////////////////////////////////////////
+int _get_vobj( char*             vspace_name, 
+               char*             vobj_name, 
+               unsigned int      vobj_type, 
+               mapping_vobj_t**  res_vobj ) 
+{
+    mapping_header_t * header = (mapping_header_t *) &seg_boot_mapping_base;
+    mapping_vspace_t * vspace = _get_vspace_base(header);
+    mapping_vobj_t * vobj     = _get_vobj_base(header);
+
+    unsigned int vspace_id;
+    unsigned int vobj_id;
+
+    // scan vspaces 
+    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
+    {
+        if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 
+        {
+            // scan vobjs
+            for (vobj_id = vspace[vspace_id].vobj_offset; 
+                 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 
+                 vobj_id++) 
+            {
+                if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 
+                {
+                    if (vobj[vobj_id].type != vobj_type) 
+                    {
+                        _tty_get_lock( 0 );
+                        _puts("*** Error in _get_obj: wrong type\n");
+                        _tty_release_lock( 0 );
+                        return -1; // wrong type
+                    }
+                    *res_vobj = &vobj[vobj_id];
+                    return 0;
+                }
+            } 
+        }
+    } 
+    _tty_get_lock( 0 );
+    _puts("*** Error in _get_obj: object not found\n");
+    _tty_release_lock( 0 );
+
+    return -2; //not found 
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// _vobj_get_vbase()
+// This function writes in vobj_vaddr the virtual base address of a vobj 
+// identified by the (vspace_name / vobj_name ) couple.
+// The vobj_type argument is here only for the purpose of checking .
+// returns 0: success, else: failed.
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _vobj_get_vbase( char*         vspace_name,
+                              char*         vobj_name,
+                              unsigned int  vobj_type,
+                              unsigned int* vobj_vaddr ) 
+{
+    mapping_vobj_t* res_vobj;
+    unsigned int    ret;
+    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
+    {
+        return ret;
+    }
+    *vobj_vaddr = res_vobj->vaddr;
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// _vobj_get_length()
+// This function writes in vobj_length the virtual base address of a vobj 
+// identified by the (vspace_name / vobj_name ) couple.
+// The vobj_type argument is here only for the purpose of checking .
+// returns 0: success, else: failed.
+/////////////////////////////////////////////////////////////////////////////
+unsigned int _vobj_get_length( char*         vspace_name, 
+                               char*         vobj_name,
+                               unsigned int  vobj_type, 
+                               unsigned int* vobj_length ) 
+{
+    mapping_vobj_t * res_vobj;
+    unsigned int ret;
+    if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 
+    {
+        return ret;
+    }
+    *vobj_length = res_vobj->length;
+    return 0;
+}
+
+
+////////////////////////////////////////////////////////////////
+// _context_switch()
+// This functions masks interruptions before calling _ctx_switch
+// (They are usually masked when we receive a isr_switch interrupt
+// because we execute ISRs with interrupt masked)
+////////////////////////////////////////////////////////////////
+void _context_switch() 
+{
+    _it_disable();
+    _ctx_switch();
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_kernel/sys_handler.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_kernel/sys_handler.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_kernel/sys_handler.h	(revision 283)
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////
+// File     : sys_handler.h
+// Date     : 01/04/2012
+// Author   : alain greiner and joel porquet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _SYS_HANDLER_H
+#define _SYS_HANDLER_H
+
+//////////////////////////////////////////////////////////////////////////////////
+//     Syscall Vector Table (indexed by syscall index)
+//////////////////////////////////////////////////////////////////////////////////
+
+extern const void * _syscall_vector[64];
+
+//////////////////////////////////////////////////////////////////////////////////
+// Prototypes os the syscall handlers (other than peripheral drivers)
+//////////////////////////////////////////////////////////////////////////////////
+
+void         _sys_ukn();
+void         _task_exit();
+void         _context_switch();
+unsigned int _local_task_id();
+unsigned int _global_task_id();
+unsigned int _thread_id();
+
+int          _tty_get_release_lock(unsigned int val);
+
+unsigned int _procs_number( unsigned int  cluster_id, 
+                            unsigned int* number );
+
+unsigned int _vobj_get_vbase( char*         vspace_name, 
+                              char*         vobj_name, 
+                              unsigned      vobj_type, 
+                              unsigned int* vobj_buffer);
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/barrier.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/barrier.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/barrier.c	(revision 283)
@@ -0,0 +1,87 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : barrier.c      
+// Date     : 01/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// These barrier.c and barrier.h files are part of the GIET nano-kernel.
+// This user-level library provides a synchronisation service between several
+// tasks sharing the same address space in a parallel multi-tasks application.
+// Neither the barrier_init(), nor the barrier_wait() function require a syscall.
+// The barrier itself must have been allocated in a shared data segment.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "barrier.h"
+
+///////////////////////////////////////////////////////////////////////////////////
+//     barrier_init()
+// This function makes a cooperative initialisation of the barrier: 
+// several tasks try to initialize the barrier, but the initialisation 
+// is done by only one task, using LL/SC instructions.
+///////////////////////////////////////////////////////////////////////////////////
+void barrier_init( giet_barrier_t * barrier, unsigned int value) {
+    unsigned int * pinit  = (unsigned int *) &barrier->init;
+    unsigned int * pcount = (unsigned int *) &barrier->count;
+
+    // parallel initialisation using atomic instructions LL/SC 
+    // inputs : pinit, pcount, value
+    // no output
+    asm volatile ("_barrier_init_test:                  \n"
+            "ll   $2,     0(%0)                   \n" /* read initial value */
+            "bnez $2,     _barrier_init_done      \n"
+            "move $3,     %2                      \n"
+            "sc   $3,     0(%0)                   \n" /* write initial value */
+            "beqz $3,     _barrier_init_test      \n"
+            "move $3,     %2                      \n"
+            "sw   $3,     0(%1)                   \n" /* write count */
+            "_barrier_init_done:                  \n"
+            :
+            : "r"(pinit), "r"(pcount), "r"(value)
+            : "$2", "$3");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+//    barrier_wait()
+// This blocking function uses LL/SC to decrement the barrier's counter.
+// Then, it uses a busy_waiting mechanism if it is not the last.
+// (because the GIET does not support dynamic task scheduling/descheduling)
+///////////////////////////////////////////////////////////////////////////////////
+void barrier_wait(giet_barrier_t * barrier) {
+    unsigned int * pcount  = (unsigned int *) &barrier->count;
+    unsigned int maxcount = barrier->init;
+    unsigned int count;
+
+    // parallel decrement barrier counter using atomic instructions LL/SC
+    // - input : pointer on the barrier counter
+    // - output : counter value
+    asm volatile ("_barrier_decrement:          \n"
+            "ll   %0, 0(%1)               \n"
+            "addi $3, %0,     -1          \n"
+            "sc   $3, 0(%1)               \n"
+            "beqz $3, _barrier_decrement  \n"
+            : "=&r"(count)
+            : "r"(pcount)
+            : "$2", "$3");
+
+    // the last task re-initializes the barrier counter to the max value,
+    // waking up all other waiting tasks
+
+    if (count == 1) {
+        // last task
+        *pcount = maxcount;
+    }
+    else {
+        // other tasks busy-wait
+        while (*pcount != maxcount) asm volatile ("nop");
+    }
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/barrier.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/barrier.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/barrier.h	(revision 283)
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : barrier.h         
+// Date     : 01/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _BARRIER_H_
+#define _BARRIER_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+//  barrier structure
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct giet_barrier_s {
+    char name[32];      // barrier name
+    unsigned int init;  // total number of participants
+    unsigned int count; // number of not yet arrived tasks
+} giet_barrier_t;
+
+//////////////////////////////////////////////////////////////////////////////
+//  access functions
+//////////////////////////////////////////////////////////////////////////////
+
+void barrier_init(giet_barrier_t * barrier, unsigned int value);
+void barrier_wait(giet_barrier_t * barrier);
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_args.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_args.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_args.h	(revision 283)
@@ -0,0 +1,47 @@
+#ifndef SRL_ARGS_H
+#define SRL_ARGS_H
+
+
+
+#define SRL_GET_MWMR(port)      (srl_mwmr_t)     APP_GET_ARG(port, VOBJ_TYPE_MWMR)
+#define SRL_GET_BARRIER(port)   (srl_barrier_t)  APP_GET_ARG(port, VOBJ_TYPE_BARRIER)
+#define SRL_GET_LOCK(port)                       APP_GET_ARG(port, VOBJ_TYPE_LOCK)
+#define SRL_GET_MEMSPACE(port)  (srl_memspace_t) APP_GET_ARG(port, VOBJ_TYPE_MEMSPACE)
+
+
+# define SRL_GET_VBASE(task_name, port, type)                                                      \
+({                                                                                                 \
+    unsigned int  vbase;                                                                           \
+    if (giet_vobj_get_vbase(APP_NAME , args->port, type, &vbase))                                  \
+    {                                                                                              \
+        srl_log_printf(NONE, "\n[ERROR] in "#task_name" task :\n");                                \
+        srl_log_printf(NONE, "          undefined port <"#port"> for channel \"%s\": %x\n",        \
+                                                                args->port, vbase);                \
+        srl_log_printf(TRACE, "*** &"#port" = %x\n\n", vbase);                                     \
+        srl_exit();                                                                                \
+    }                                                                                              \
+    else                                                                                           \
+        srl_log_printf(TRACE, "%s:%d: arg of %s for %s, from %s; &"#port" = %x\n\n",               \
+                            __FILE__, __LINE__, APP_NAME, #task_name, #port, vbase);               \
+    vbase;                                                                                         \
+})
+
+
+#define SRL_GET_CONST(port)                                                                        \
+({                                                                                                 \
+    unsigned int vbase;                                                                            \
+    if (giet_vobj_get_vbase(APP_NAME, args->port, VOBJ_TYPE_CONST, &vbase)) {                      \
+        srl_log_printf(NONE, "\n[ERROR] in some task :\n");                                        \
+        srl_log_printf(NONE, "          undefined port <"#port"> for channel \"%s\": %x\n",        \
+                                                                args->port, vbase);                \
+        srl_log_printf(TRACE, "*** &"#port" = %x\n\n", vbase);                                     \
+        srl_exit();                                                                                \
+    }                                                                                              \
+    else                                                                                           \
+        srl_log_printf(TRACE, "%s:%d: arg of %s, from %s; &"#port" = %x\n\n",                      \
+                            __FILE__, __LINE__, APP_NAME, #port, vbase);                           \
+    *(int *) vbase;                                                                                \
+})
+
+
+#endif
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_barrier.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_barrier.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_barrier.h	(revision 283)
@@ -0,0 +1,39 @@
+/*
+ * This file is part of DSX, development environment for static
+ * SoC applications.
+ * 
+ * This file is distributed under the terms of the GNU General Public
+ * License.
+ * 
+ *     Laboratoire d'informatique de Paris 6 / ASIM, France
+ * 
+ *  $Id$
+ */
+
+#ifndef SRL_BARRIER_H_
+#define SRL_BARRIER_H_
+
+/**
+ * @file
+ * @module{SRL}
+ * @short Barrier operations
+ */
+
+#include "barrier.h"
+
+
+typedef giet_barrier_t * srl_barrier_t;
+
+#define srl_barrier_wait(bar) barrier_wait(bar)
+
+#endif
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_endianness.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_endianness.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_endianness.h	(revision 283)
@@ -0,0 +1,91 @@
+#ifndef SRL_ENDIANNESS_H_
+#define SRL_ENDIANNESS_H_
+
+#include "srl_public_types.h"
+
+/** @this reads a big endian 16 bits value */
+#  define endian_le16(x)    (x)
+/** @this reads a big endian 32 bits value */
+#  define endian_le32(x)    (x)
+/** @this reads a big endian 64 bits value */
+//#  define endian_le64(x)    (x)
+/** @this reads a little endian 16 bits value */
+#  define endian_be16(x)    endian_swap16(x)
+/** @this reads a little endian 32 bits value */
+#  define endian_be32(x)    endian_swap32(x)
+/** @this reads a little endian 64 bits value */
+//#  define endian_be64(x)    endian_swap64(x)
+
+/** @internal */
+static inline uint16_t endian_swap16(uint16_t x) {
+    return (x >> 8) | (x << 8);
+}
+
+
+/** @internal */
+static inline uint32_t endian_swap32(uint32_t x) {
+    return (((x >> 24) & 0x000000ff) |
+            ((x >> 8 ) & 0x0000ff00) |
+            ((x << 8 ) & 0x00ff0000) |
+            ((x << 24) & 0xff000000));
+}
+
+
+/** @internal *//*
+                   static inline uint64_t __endian_swap64(uint64_t x)
+                   {
+                   return (((uint64_t)endian_swap32(x      ) << 32) |
+                   ((uint64_t)endian_swap32(x >> 32)      ));
+                   }*/
+
+static inline uint32_t srl_uint32_le_to_machine(uint32_t x) {
+    return endian_le32(x);
+}
+
+
+static inline uint32_t srl_uint32_machine_to_le(uint32_t x) {
+    return endian_le32(x);
+}
+
+
+static inline uint32_t srl_uint32_be_to_machine(uint32_t x) {
+    return endian_be32(x);
+}
+
+
+static inline uint32_t srl_uint32_machine_to_be(uint32_t x) {
+    return endian_be32(x);
+}
+
+
+static inline uint16_t srl_uint16_le_to_machine(uint16_t x) {
+    return endian_le16(x);
+}
+
+
+static inline uint16_t srl_uint16_machine_to_le(uint16_t x) {
+    return endian_le16(x);
+}
+
+
+static inline uint16_t srl_uint16_be_to_machine(uint16_t x) {
+    return endian_be16(x);
+}
+
+
+static inline uint16_t srl_uint16_machine_to_be(uint16_t x) {
+    return endian_be16(x);
+}
+
+
+#endif
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_hw_helpers.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_hw_helpers.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_hw_helpers.h	(revision 283)
@@ -0,0 +1,87 @@
+#ifndef SRL_HW_HELPERS_H
+#define SRL_HW_HELPERS_H
+
+/**
+ * @file
+ * @module{SRL}
+ * @short Miscellaneous APIs
+ */
+
+#include "stdio.h"
+
+
+/**
+  Standard API call, expands to nothing for this implementation.
+  */
+#define srl_busy_cycles(n) do{}while(0)
+
+//void useless(void *pointless,...){}
+/**
+  @this flushes the cache line containing the address.
+  */
+//TODO
+#define srl_dcache_flush_addr 0
+
+/*
+   static inline cpu_dcache_invld(void *ptr){
+   asm volatile (                                
+   " cache %0, %1"                            
+   : : "i" (0x11) , "R" (*(uint8_t*)(ptr))    
+   : "memory"                                
+   );                            
+   }
+   */
+
+/**
+  @this flushes a memory zone from cache.
+  */
+//TODO
+//void dcache_flush(const void * addr, size_t size)
+#define srl_dcache_flush_zone dcache_flush
+
+/**
+  @this waits for at least the given time (in cycles). The actual
+  time spent in this call is not predictable.
+
+  @param time Number of cycles to wait for
+  */
+void srl_sleep_cycles(unsigned int time);
+
+/**
+  @this returns the absolute timestamp counter from the
+  initialization of the platform.
+
+  @return Cycles from the initialization of the system
+  */
+static inline unsigned int srl_cycle_count() {
+    return giet_proctime();
+}
+
+
+/**
+  @this aborts the current execution. On most systems, @this will
+  simply hang.
+  */
+static inline void srl_abort() {
+    asm volatile ("break 0");
+    while (1);
+}
+
+
+/**
+ *
+ */
+static inline void srl_exit() {
+    giet_exit();
+}
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_lock.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_lock.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_lock.h	(revision 283)
@@ -0,0 +1,60 @@
+/*
+ * This file is part of DSX, development environment for static
+ * SoC applications.
+ * 
+ * This file is distributed under the terms of the GNU General Public
+ * License.
+ * 
+ * Copyright (c) 2006, Nicolas Pouillon, <nipo@ssji.net>
+ *     Laboratoire d'informatique de Paris 6 / ASIM, France
+ * 
+ *  $Id$
+ */
+
+#ifndef SRL_LOCK_H_
+#define SRL_LOCK_H_
+
+/**
+ * @file
+ * @module{SRL}
+ * @short Lock operations
+ */
+
+#include "spin_lock.h"
+
+typedef giet_lock_t * srl_lock_t;
+
+/**
+   @this takes a lock.
+
+   @param lock The lock object
+ */
+#define srl_lock_lock(lock) lock_acquire(lock);
+
+/**
+   @this releases a lock.
+
+   @param lock The lock object
+ */
+#define srl_lock_unlock( lock ) lock_release(lock);
+
+/**
+   @this tries to take a lock. @this returns whether the lock was
+   actually taken.
+
+   @param lock The lock object
+   @return 0 if the lock was taken successfully
+ */
+#define srl_lock_try_lock( lock ) lock_try_acquire( lock );
+
+#endif
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_log.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_log.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_log.h	(revision 283)
@@ -0,0 +1,79 @@
+/*
+ * This file is part of DSX, development environment for static
+ * SoC applications.
+ * 
+ * This file is distributed under the terms of the GNU General Public
+ * License.
+ * 
+ * Copyright (c) 2006, Nicolas Pouillon, <nipo@ssji.net>
+ *     Laboratoire d'informatique de Paris 6 / ASIM, France
+ * 
+ *  $Id$
+ */
+
+#ifndef SRL_LOG_H_
+#define SRL_LOG_H_
+
+/**
+ * @file
+ * @module{SRL}
+ * @short Debug messages
+ */
+
+#include "stdio.h"
+#include "giet_config.h"
+#include "srl_hw_helpers.h"
+
+/** @internal */
+enum __srl_verbosity {
+    VERB_NONE,
+    VERB_TRACE,
+    VERB_DEBUG,
+    VERB_MAX,
+};
+
+
+void _srl_log(const char *);
+void _srl_log_printf(const char *, ...);
+
+#define GET_VERB_(x,y) x##y
+#define GET_VERB(x) GET_VERB_(VERB_,x)
+
+/**
+   @this prints a message if the current verbosity is sufficient.
+
+   @param l Minimal verbosity of the message
+   @param c Message to print
+ */
+#define srl_log( l, c ) do {										   \
+		if (GET_VERB(l) <= GET_VERB(CONFIG_SRL_VERBOSITY)) {		   \
+            giet_tty_printf(c);                                             \
+		}															   \
+	} while (0)
+
+/**
+   @this prints a message if the current verbosity is sufficient.
+
+   @param l Minimal verbosity of the message
+   @param c Message to print, with a printf-like syntax
+ */
+#define srl_log_printf( l, ... ) do {                                   \
+		if (GET_VERB(l) <= GET_VERB(CONFIG_SRL_VERBOSITY)) {		    \
+            giet_tty_printf(__VA_ARGS__);                                    \
+		}															    \
+	} while (0)
+
+/**
+   @this is the same as @ref #assert.
+    TODO change the location?
+ */
+#define srl_assert(expr)												\
+    do {																\
+        if ( ! (expr) ) {												\
+            srl_log_printf(NONE, "assertion (%s) failed on %s:%d !\n",  \
+						   #expr, __FILE__, __LINE__ );					\
+            srl_abort();													\
+        }																\
+    } while(0)
+
+#endif
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_memspace.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_memspace.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_memspace.h	(revision 283)
@@ -0,0 +1,41 @@
+#ifndef SRL_MEMSPACE_H
+#define SRL_MEMSPACE_H
+
+#include "srl_public_types.h"
+
+#include <memspace.h>
+
+/**
+ * @file
+ * @module{SRL}
+ * @short Memory resources
+ */
+
+
+/**
+   The memspace abstract type.
+ */
+
+
+typedef giet_memspace_t * srl_memspace_t;
+
+/**
+   @this retrieves the size of a memspace
+
+   @param memsp The memspace
+   @return the size of the memspace
+ */
+#define SRL_MEMSPACE_SIZE(memsp) ((memsp)->size)
+#define SRL_MEMSPACE_ADDR(memsp) ((memsp)->buffer)
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_mwmr.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_mwmr.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_mwmr.h	(revision 283)
@@ -0,0 +1,23 @@
+#ifndef SRL_MWMR_H_
+#define SRL_MWMR_H_
+
+#include "mwmr_channel.h"
+
+typedef  mwmr_channel_t * srl_mwmr_t;
+
+#define srl_mwmr_write(a, b, c) mwmr_write(a, (unsigned int *) b, (unsigned int) c)
+#define srl_mwmr_read(a, b, c) mwmr_read(a, (unsigned int *) b, (unsigned int) c)
+#define srl_mwmr_try_write(a, b, c) nb_mwmr_write(a, (unsigned int *) b, (unsigned int) c)
+#define srl_mwmr_try_read(a, b, c) nb_mwmr_read(a, (unsigned int *) b, (unsigned int) c)
+
+
+#endif //fin de SRL_MWMR_H_
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_private_types.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_private_types.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_private_types.c	(revision 283)
@@ -0,0 +1,48 @@
+
+#include "srl_private_types.h"
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+//  mempcy()
+// GCC requires this function. Taken from MutekH.
+////////////////////////////////////////////////////////////////////////////////////////
+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;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+//  mempcy()
+// GCC requires this function. Taken from MutekH.
+////////////////////////////////////////////////////////////////////////////////////////
+inline void * memset(void * dst, int s, size_t count) {
+    char * a = (char *) dst;
+    while (count--){
+        *a++ = (char)s;
+    }
+    return dst;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_private_types.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_private_types.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_private_types.h	(revision 283)
@@ -0,0 +1,17 @@
+#ifndef SRL_PRIVATE_TYPES_H
+#define SRL_PRIVATE_TYPES_H
+
+/**
+ * @file
+ * @module{SRL}
+ * @short Abstract types definitions
+ */
+
+
+
+/**
+ * copy to the cache avoiding the optimisations done the compiler (volatile)
+ */
+#define cpu_mem_write_32(addr, data) *((volatile uint32_t*)(addr)) = data 
+
+#endif
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_public_types.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_public_types.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_public_types.h	(revision 283)
@@ -0,0 +1,42 @@
+#ifndef SRL_PUBLIC_TYPES_H
+#define SRL_PUBLIC_TYPES_H
+
+/**
+ * @file
+ * @module{SRL}
+ * @short Abstract types definitions
+ */
+
+typedef unsigned long       uint_t;
+typedef signed long         sint_t;
+
+typedef unsigned char       uint8_t;
+typedef signed char         sint8_t;
+typedef signed short int    int8_t;
+
+typedef unsigned short int  uint16_t;
+typedef signed short int    sint16_t;
+typedef signed short int    int16_t;
+
+typedef unsigned int        uint32_t;
+typedef signed int          sint32_t;
+typedef signed int          int32_t;
+
+typedef sint32_t            error_t;
+typedef uint_t              bool_t;
+
+typedef void *srl_buffer_t;
+
+
+#ifndef NULL
+#define NULL                (void*)0
+#endif
+
+/** Get integer minimum value */
+#define __MIN(a, b) ({ const typeof(a) __a = (a); const typeof(b) __b = (b); __b < __a ? __b : __a; })
+    
+/** Get integer maximum value */
+#define __MAX(a, b) ({ const typeof(a) __a = (a); const typeof(b) __b = (b); __b > __a ? __b : __a; })
+
+
+#endif
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_sched_wait.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_sched_wait.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_sched_wait.c	(revision 283)
@@ -0,0 +1,77 @@
+/*
+ * This file is part of MutekH.
+ * 
+ * MutekH is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * MutekH 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with MutekH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * Copyright (c) UPMC, Lip6, SoC
+ */
+
+#include "srl_private_types.h"
+#include "srl_sched_wait.h"
+#include "srl_hw_helpers.h"
+#include "stdio.h"
+
+#define endian_cpu32(x) (x)
+
+#define DECLARE_WAIT(name, cmp)                                 \
+                                                                \
+void srl_sched_wait_##name(void * addr, sint32_t val) {         \
+    srl_dcache_flush_addr(addr);                                \
+    if (((sint32_t) * ((unsigned int *) addr)) cmp val)         \
+    return;                                                     \
+    do {                                                        \
+        srl_sched_wait_priv(100);??                             \
+        srl_dcache_flush_addr(addr);                            \
+    } while (((sint32_t) * ((unsigned int *) addr)) cmp val);   \
+}
+
+
+
+DECLARE_WAIT(eq, ==)
+
+DECLARE_WAIT(ne, !=)
+
+DECLARE_WAIT(le, <=)
+
+DECLARE_WAIT(ge, >=)
+
+DECLARE_WAIT(lt, <)
+
+DECLARE_WAIT(gt, >)
+
+    //TODO
+void srl_sched_wait_priv(uint32_t date) {
+    do {
+        context_switch();
+    } while (srl_cycle_count() > date);
+}
+
+void srl_sleep_cycles(uint32_t n) {
+    uint32_t next_run_to = srl_cycle_count() + n;
+
+    while (srl_cycle_count() < next_run_to) {
+        srl_sched_wait_priv(next_run_to);
+    }
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_sched_wait.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_sched_wait.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/libsrl/srl_sched_wait.h	(revision 283)
@@ -0,0 +1,49 @@
+#ifndef SRL_SCHED_WAIT_H
+#define SRL_SCHED_WAIT_H
+
+#include "srl_public_types.h"
+
+/**
+ * @file
+ * @module{SRL}
+ * @short Smart waiting tools
+ */
+
+#define DECLARE_WAIT(name, cmp)                                       \
+/**                                                                           \
+   @this makes the current task sleep until the value pointed at @tt addr     \
+   asserts the following test:                                                \
+                                                                              \
+   @code                                                                      \
+   (*addr cmp val)                                                            \
+   @end code                                                                  \
+                                                                              \
+   @param addr The address to poll                                            \
+   @param val The value to compare to                                         \
+*/                                                                            \
+                                                                              \
+void srl_sched_wait_##name(void *addr, sint32_t val );
+
+DECLARE_WAIT(eq, ==)
+DECLARE_WAIT(ne, !=)
+DECLARE_WAIT(le, <=)
+DECLARE_WAIT(ge, >=)
+DECLARE_WAIT(lt, <)
+DECLARE_WAIT(gt, >)
+
+#undef DECLARE_WAIT
+
+
+void srl_sleep_cycles(unsigned int n);
+
+#endif
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/malloc.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/malloc.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/malloc.c	(revision 283)
@@ -0,0 +1,1218 @@
+
+#include "malloc.h"
+#include "malloc_private.h"
+#include "stdio.h"
+
+heap_ll * _heap_head[NB_TASKS_MAX];
+
+heap_ll * _remote_free_list[NB_TASKS_MAX] = { 0 };
+giet_lock_t lock_rf_list[NB_TASKS_MAX] = { {"toto",0} };
+
+unsigned int _heap_base[NB_TASKS_MAX] = { -1 };
+unsigned int _heap_length[NB_TASKS_MAX] = { -1 };
+
+int _first_malloc[NB_TASKS_MAX] = { 0 };
+
+
+#if MALLOC_SELECTED == 1
+
+#elif MALLOC_SELECTED == 2
+heap_ll * _prev_next_last_allocted[NB_TASKS_MAX] = { 0 };
+#else
+#define MAX_SIZE_POW2_TAB 28 
+#define GET_TAB_INDEX(size)                 (size == 0x00000008) ? 0 :\
+                                            (size <= 0x00000010) ? 1 :\
+                                            (size <= 0x00000020) ? 2 :\
+                                            (size <= 0x00000040) ? 3 :\
+                                            (size <= 0x00000080) ? 4 :\
+                                            (size <= 0x00000100) ? 5 :\
+                                            (size <= 0x00000200) ? 6 :\
+                                            (size <= 0x00000400) ? 7 :\
+                                            (size <= 0x00000800) ? 8 :\
+                                            (size <= 0x00001000) ? 9 :\
+                                            (size <= 0x00002000) ? 10 :\
+                                            (size <= 0x00004000) ? 11 :\
+                                            (size <= 0x00008000) ? 12 :\
+                                            (size <= 0x00010000) ? 13 :\
+                                            (size <= 0x00020000) ? 14 :\
+                                            (size <= 0x00040000) ? 15 :\
+                                            (size <= 0x00080000) ? 16 :\
+                                            (size <= 0x00100000) ? 17 :\
+                                            (size <= 0x00200000) ? 18 :\
+                                            (size <= 0x00400000) ? 19 :\
+                                            (size <= 0x00800000) ? 20 :\
+                                            (size <= 0x01000000) ? 21 :\
+                                            (size <= 0x02000000) ? 22 :\
+                                            (size <= 0x04000000) ? 23 :\
+                                            (size <= 0x08000000) ? 24 :\
+                                            (size <= 0x10000000) ? 25 :\
+                                            (size <= 0x20000000) ? 26 :\
+                                                                   27
+
+heap_ll * _pow2tab[NB_TASKS_MAX][MAX_SIZE_POW2_TAB] = {{ 0 }};
+#endif
+
+
+#if DEBUG_MALLOC == 1              
+#define giet_printf(...)                \
+    ({                                      \
+     giet_tty_printf(__VA_ARGS__);       \
+     })                                  
+#else
+#define giet_printf(...) ({   })
+#endif
+
+
+
+#if MALLOC_SELECTED == 1
+/*########################################################################*/
+/**************************************************************************/
+/**********                     WORST-FIT                       ***********/
+/**************************************************************************/
+/*########################################################################*/
+heap_ll *get_prev_fit_chunk(unsigned int size) {
+    int task_id = giet_global_task_id();
+    int check_remote_free_list = 0;
+after_remote_list_check :
+    if (_heap_head[task_id] == 0x0) {
+        if(check_remote_free_list == 0)
+        {
+            heap_ll * poped_block;
+            heap_ll * head_of_rf;
+            check_remote_free_list = 1;
+
+            head_of_rf = pop_ptr();
+
+            while((poped_block = pop_remote_free_list(&head_of_rf)) != 0x0)
+            {
+                update_chunk_list((unsigned int)poped_block, poped_block->chunk_length);
+            }
+            goto after_remote_list_check; 
+        }
+        return ((heap_ll *) 0x01);
+    }
+    int found = 0;
+    heap_ll * ptr_to_chunk_list = _heap_head[task_id];
+    heap_ll * tmp = 0x0;
+    heap_ll * prev = 0x0;
+    heap_ll * prev_tmp = 0x0;
+    while (ptr_to_chunk_list != 0x0) {
+        if (size <= ptr_to_chunk_list->chunk_length) {
+            if (tmp == 0x0 || ptr_to_chunk_list->chunk_length > tmp->chunk_length) {
+                prev_tmp = prev;
+                tmp = ptr_to_chunk_list;
+                found = 1;
+            }
+        }
+        prev = ptr_to_chunk_list;
+        ptr_to_chunk_list = ptr_to_chunk_list->next;
+    }
+    if (found == 1)
+    {
+        return prev_tmp; // case when prev_tmp == 0x0 is handled in the calling function
+    }
+    else
+    {
+        if(check_remote_free_list == 0)
+        {
+            heap_ll * poped_block;
+            heap_ll * head_of_rf;
+            check_remote_free_list = 1;
+
+            head_of_rf = pop_ptr();
+
+            while((poped_block = pop_remote_free_list(&head_of_rf)) != 0x0)
+            {
+                update_chunk_list((unsigned int)poped_block, poped_block->chunk_length);
+            }
+            goto after_remote_list_check; 
+        }
+        return (heap_ll *) 0x1;
+    }
+}
+
+
+
+void * malloc(unsigned int size) {
+    int task_id = giet_global_task_id();
+
+    giet_printf("############ MALLOC ############\n\n");
+    if (size == 0) {
+
+        giet_printf(" SIZE = 0 \n");
+        return 0x0;
+    }
+
+    /****** First call to malloc ******/
+    if (_first_malloc[task_id] == 0) {
+        giet_heap_info(&_heap_base[task_id], &_heap_length[task_id]);
+
+        if (_heap_length[task_id] == 0) {
+            giet_printf("*** Error: Malloc called in task %d and no heap was defined.\n", task_id);
+            return 0x0;
+        }
+        _heap_head[task_id] = (heap_ll *) _heap_base[task_id];
+        _heap_head[task_id]->chunk_length = _heap_length[task_id];
+        _heap_head[task_id]->next = 0x0;
+
+
+        _first_malloc[task_id] = 1;
+    }
+
+    /****** Size align ******/
+    int size_align = size;
+    if (size % 4 != 0) {
+        size_align = ((size / 4) + 1) * 4;
+    }
+
+
+
+    giet_printf("Looking for size : %d\n", size_align + 4);
+    /****** Get prev victim from the chunks list ******/
+    heap_ll *victim;
+    heap_ll *prev_victim;
+    //// WORST
+
+    if ((prev_victim = get_prev_fit_chunk(size_align + 4)) == (heap_ll *) 0x1) {
+        return 0x0;		// no chunk of this size avaiable, 0x1 : no suitable chunk found
+    }
+    else {
+        if (prev_victim != 0x0)	{
+            // victim != HEAD
+            victim = prev_victim->next;
+        }
+        else {
+            victim = _heap_head[task_id];
+        }
+    }
+    /****** Get Victim Base ******/
+    unsigned int victim_vbase = (unsigned int) victim;	// overhead
+
+    /****** update the chunks list ******/
+    if (victim->chunk_length == size_align + 4) {
+        // if it is an exact match
+        if (prev_victim == 0x0)	{
+            // if victim == head
+            _heap_head[task_id] = victim->next;
+        }
+        else {
+            prev_victim->next = victim->next;
+        }
+    } 
+    else {
+        // if its not an exact match then update chunk base and length
+        heap_ll * tmp_chunk = victim;
+        victim = (heap_ll *) (((unsigned int) victim) + (size_align + 4));
+
+        giet_printf("NEXT CHUNK is at @ : 0x%x + 0x%x = 0x%x\n",
+                (unsigned int) tmp_chunk,
+                (unsigned int) ((size_align + 4) / 4),
+                (unsigned int) victim);
+
+        victim->chunk_length = tmp_chunk->chunk_length - (size_align + 4);
+        victim->next = tmp_chunk->next;
+        if (prev_victim == 0x0) {
+            _heap_head[task_id] = victim;
+        }
+        else {
+            prev_victim->next = victim;
+        }
+    }
+
+    /****** Write Overhead ******/
+    *((unsigned int *) victim_vbase) = size_align;	// writing overhead on the first word
+
+    giet_printf("BLOCK SUCCESSFULLY ALLOCATED at @ 0x%x user will write at @ 0x%x\n\n"\
+            ,(unsigned int)(victim_vbase),(unsigned int) (victim_vbase + 4));
+    return (unsigned int *) (victim_vbase + 4);
+}
+
+
+
+/* this function tries to merge the block to free with chunks in the list if
+ * they are contiguous
+ * the block can be merged two times.
+ */
+void update_chunk_list(unsigned int block_base, unsigned int block_length) {
+    /* entire heap is allocated : create a new block of size block_length and give it to the head  */
+    int task_id = giet_global_task_id();
+    if (_heap_head[task_id] == 0x0) {
+        ((heap_ll *) block_base)->chunk_length = block_length;
+        ((heap_ll *) block_base)->next = 0x0;
+        _heap_head[task_id] = ((heap_ll *) block_base);
+
+        giet_printf("****** NEW BLOCK ******\n"
+                "@ : %x\n"
+                "Length : %d o\n"
+                "***********************\n",
+                block_base,
+                (unsigned int) (((heap_ll *) block_base)->chunk_length));
+        return;
+    }
+
+
+    /* Test for each Chunk in my list if the block can be merged with */
+    heap_ll *ptr_to_chunk_list = _heap_head[task_id]; // move through the list
+    heap_ll *prev = 0x0; // pointer on the previous visited chunk in the list
+    heap_ll *prev_block_base = 0x0; // pointer on the previous chunk of the chunk that contains the merged block in the list
+    unsigned int chunk_length;
+    int block_merged = 0; // =1 when the block has already been merged with a chunk in the list
+    while (ptr_to_chunk_list != 0x0) {
+        chunk_length = ptr_to_chunk_list->chunk_length;
+        /*  [.....|ptr|block|.....] */
+        if ((unsigned int) (ptr_to_chunk_list) + chunk_length == block_base) {
+
+            giet_printf("****** BLOCK MERGED ******\n"
+                    "CHUNK : %x of size %d o\n"
+                    "merged with \n"
+                    "BLOCK : %x of size %d o\n"
+                    "***********************\n",
+                    (unsigned int) ptr_to_chunk_list,
+                    ptr_to_chunk_list->chunk_length, block_base,
+                    block_length);
+
+            /* update the size */
+            ptr_to_chunk_list->chunk_length = chunk_length + block_length;
+
+            /* [.....|ptr|[block|old_ptr]|.....]
+             *  remove ptr from the list
+             *  update next pointer
+             *  update the previous chunk of block base to point to ptr
+             */
+            if (block_merged == 1) {
+                prev->next = ptr_to_chunk_list->next;
+                ptr_to_chunk_list->next = ((heap_ll *) block_base)->next;
+                if (prev_block_base != 0x0) {
+                    prev_block_base->next = ptr_to_chunk_list;
+                }
+                else {
+                    _heap_head[task_id] = ptr_to_chunk_list;
+                }
+            }
+            /****** for next turn ******/
+            block_base = (unsigned int) ptr_to_chunk_list;
+            block_length = ptr_to_chunk_list->chunk_length;
+
+            giet_printf("****** NEW BLOCK ******\n"
+                    "@ : %x\n"
+                    "Length : %d o\n"
+                    "***********************\n",
+                    (unsigned int) ptr_to_chunk_list,
+                    (unsigned int) (ptr_to_chunk_list->chunk_length));
+            prev_block_base = prev;
+            prev = ptr_to_chunk_list;
+            ptr_to_chunk_list = ptr_to_chunk_list->next;
+            block_merged = 1;
+            continue;
+
+        } // end [.....|ptr|block|.....]
+        /*  [......|block|ptr|.....] */
+        if (block_base + block_length == (unsigned int) ptr_to_chunk_list) {
+
+            giet_printf("****** BLOCK MERGED ******\n"
+                    "BLOCK : %x of size %d o\n"
+                    "merged with \n"
+                    "CHUNK : %x of size %d o\n"
+                    "***********************\n",
+                    block_base, block_length,
+                    (unsigned int) ptr_to_chunk_list,
+                    ptr_to_chunk_list->chunk_length);
+
+            /* update the size */
+            ((heap_ll *) block_base)->chunk_length = block_length + chunk_length;
+
+            /* [.....|block|ptr|......] */
+            if (block_merged == 0) {
+                /* update next pointer
+                 *  update the previous chunk of ptr to point to block_base
+                 */
+                ((heap_ll *) block_base)->next = ptr_to_chunk_list->next;
+                if (prev == 0x0) {
+                    _heap_head[task_id] = ((heap_ll *) block_base);
+                }
+                else {
+                    prev->next = ((heap_ll *) block_base);
+                }
+            }
+            /* [.....[old_ptr|block]|ptr|......] */
+            else {
+                /* remove ptr from the list */
+                prev->next = ptr_to_chunk_list->next;
+            }
+
+            ptr_to_chunk_list = ((heap_ll *) block_base);
+            block_length = ptr_to_chunk_list->chunk_length;
+
+            giet_printf("****** NEW BLOCK ******\n"
+                    "@ : %x\n"
+                    "Length : %d o\n"
+                    "***********************\n",
+                    (unsigned int) ptr_to_chunk_list,
+                    (unsigned int) (ptr_to_chunk_list->chunk_length));
+            prev_block_base = prev;
+            block_merged = 1;
+        } // end [......|block|ptr|.....]
+        prev = ptr_to_chunk_list;
+        ptr_to_chunk_list = ptr_to_chunk_list->next;
+    } // end while
+    if (block_merged == 1) {
+        return;
+    }
+    /* if the block cant be merge
+     *  create new block and add it to the end of the list 
+     */
+    ((heap_ll *) block_base)->chunk_length = block_length;
+    ((heap_ll *) block_base)->next = 0x0;
+    prev->next = ((heap_ll *) block_base);
+
+    giet_printf("****** NEW BLOCK ******\n"
+            "@ : %x\n"
+            "Length : %d o\n"
+            "***********************\n",
+            block_base,
+            (unsigned int) (((heap_ll *) block_base)->chunk_length));
+    return;
+
+}
+
+
+
+/*########################################################################*/
+/**************************************************************************/
+/**********                 END WORST-FIT                       ***********/
+/**************************************************************************/
+/*########################################################################*/
+#elif MALLOC_SELECTED == 2 // Next Fit 
+/*########################################################################*/
+/**************************************************************************/
+/**********                   NEXT-FIT                          ***********/
+/**************************************************************************/
+/*########################################################################*/
+
+heap_ll * get_prev_fit_chunk(unsigned int size) {
+    int task_id = giet_global_task_id();
+    int check_remote_free_list = 0;
+after_remote_list_check_n : //n for next_fit
+    if (_heap_head[task_id] == 0x0) {
+        if(check_remote_free_list == 0)
+        {
+            heap_ll * poped_block;
+            heap_ll * head_of_rf;
+            check_remote_free_list = 1;
+
+            head_of_rf = pop_ptr();
+
+            while((poped_block = pop_remote_free_list(&head_of_rf)) != 0x0)
+            {
+                update_chunk_list((unsigned int)poped_block, poped_block->chunk_length);
+            }
+            goto after_remote_list_check_n; 
+        }
+        return ((heap_ll *) 0x1);
+    }
+
+    heap_ll * ptr_to_chunk_list;
+    heap_ll * prev = 0x0;
+    heap_ll * tmp_turn = 0x0;
+
+    if (_prev_next_last_allocted[task_id] == 0x0 || _prev_next_last_allocted[task_id]->next == 0x0) {
+        ptr_to_chunk_list = _heap_head[task_id];
+    }
+    else
+    {
+        ptr_to_chunk_list = _prev_next_last_allocted[task_id]->next;
+    }
+
+    tmp_turn = (ptr_to_chunk_list == 0x0)?_heap_head[task_id]:ptr_to_chunk_list;
+    do {
+        if (ptr_to_chunk_list == 0x0) {
+            // simulate circular list
+            ptr_to_chunk_list = _heap_head[task_id];
+            if (ptr_to_chunk_list == tmp_turn) break;
+        }
+
+        if (size <= ptr_to_chunk_list->chunk_length) {
+            return prev;
+        }
+        prev = ptr_to_chunk_list;
+        ptr_to_chunk_list = ptr_to_chunk_list->next;
+    } while (ptr_to_chunk_list != tmp_turn);
+    if(check_remote_free_list == 0)
+    {
+        heap_ll * poped_block;
+        heap_ll * head_of_rf;
+        check_remote_free_list = 1;
+
+        head_of_rf = pop_ptr();
+
+        while((poped_block = pop_remote_free_list(&head_of_rf)) != 0x0)
+        {
+            update_chunk_list((unsigned int)poped_block, poped_block->chunk_length);
+        }
+        goto after_remote_list_check_n; 
+    }
+
+    return (heap_ll *) 0x1;
+}
+
+
+void * malloc(unsigned int size) {
+
+    int task_id = giet_global_task_id();
+
+    giet_printf("############ MALLOC ############\n\n");
+    if (size == 0) {
+
+        giet_printf(" SIZE = 0 \n");
+        return 0x0;
+    }
+
+    /****** First call to malloc ******/
+    if (_first_malloc[task_id] == 0) {
+        giet_heap_info(&_heap_base[task_id], &_heap_length[task_id]);
+
+        if (_heap_length[task_id] == 0) {
+            giet_printf("*** Error: Malloc called in task %d while no heap was defined.\n", task_id);
+            return 0x0;
+        }
+
+        _heap_head[task_id] = (heap_ll *) _heap_base[task_id];
+        _heap_head[task_id]->chunk_length = _heap_length[task_id];
+        _heap_head[task_id]->next = 0x0;
+
+        _prev_next_last_allocted[task_id] = 0x0;
+
+        _first_malloc[task_id] = 1;
+    }
+
+    /****** Size align ******/
+    int size_align = size;
+    if (size % 4 != 0) {
+        size_align = ((size / 4) + 1) * 4;
+    }
+
+
+
+    giet_printf("Looking for size : %d\n", size_align + 4);
+    /****** Get prev victim from the chunks list ******/
+    heap_ll *victim;
+    heap_ll *prev_victim;
+
+    if ((prev_victim = get_prev_fit_chunk(size_align + 4)) == (heap_ll *) 0x1) {
+        return 0x0;		// no chunk of this size avaiable, 0x1 : no suitable chunk found
+    }
+    else {
+        if (prev_victim != 0x0) {
+            // victim != _next_last_allocted
+            if (prev_victim->next == 0x0) {
+                // victim == HEAD
+                victim = _heap_head[task_id];
+            }
+            else {
+                victim = prev_victim->next;
+            }
+        }
+        else
+        {
+            if (_prev_next_last_allocted[task_id] == 0x0 || _prev_next_last_allocted[task_id]->next == 0x0) {
+                victim =_heap_head[task_id];
+            }
+            else {
+                victim = _prev_next_last_allocted[task_id]->next;
+            }
+        }
+    }
+
+    /****** Get Victim Base ******/
+    unsigned int victim_vbase = (unsigned int) victim; // overhead
+
+    /****** update the chunks list ******/
+    if (victim->chunk_length - (size_align + 4) < 8) {
+        // if it is an exact match
+        size_align = size_align + (victim->chunk_length - (size_align + 4));
+
+        if (prev_victim == 0x0)	{
+            // if victim == head
+            if (_prev_next_last_allocted[task_id] == 0x0 || _prev_next_last_allocted[task_id]->next == 0x0) {
+                _heap_head[task_id] = victim->next;
+            }
+            else {
+                _prev_next_last_allocted[task_id]->next = victim->next;
+            }
+            _prev_next_last_allocted[task_id] = victim->next;
+        }
+        else {
+            if (prev_victim->next == 0x0) {
+                _heap_head[task_id] = victim->next;
+            }
+            else {
+                prev_victim->next = victim->next;
+            }
+            _prev_next_last_allocted[task_id] = prev_victim;
+        }
+    } 
+    else {
+        // if its not an exact match then update chunk base and length
+        heap_ll * tmp_chunk = victim;
+        victim = (heap_ll *) (((unsigned int) victim) + (size_align + 4));
+
+        giet_printf("NEXT CHUNK is at @ : 0x%x + 0x%x = 0x%x\n",
+                (unsigned int) tmp_chunk,
+                (unsigned int) ((size_align + 4) / 4),
+                (unsigned int) victim);
+
+        victim->chunk_length = tmp_chunk->chunk_length - (size_align + 4);
+        victim->next = tmp_chunk->next;
+        if (prev_victim == 0x0) {
+            if (_prev_next_last_allocted[task_id] == 0x0 || _prev_next_last_allocted[task_id]->next == 0x0) {
+                _heap_head[task_id] = victim;
+            }
+            else {
+                _prev_next_last_allocted[task_id]->next = victim;
+            }
+            _prev_next_last_allocted[task_id] = victim->next;
+        }
+        else {
+            if (prev_victim->next == 0x0) {
+                _heap_head[task_id] = victim;
+            }
+            else {
+                prev_victim->next = victim;
+            }
+            _prev_next_last_allocted[task_id] = prev_victim;
+        }
+    }
+
+    /****** Write Overhead ******/
+    *((unsigned int *) victim_vbase) = size_align;	// writing overhead on the first word
+
+    giet_printf("BLOCK SUCCESSFULLY ALLOCATED at @ 0x%x user will write at @ 0x%x\n\n"\
+            ,(unsigned int)(victim_vbase),(unsigned int )(victim_vbase + 4));
+    return (unsigned int *) (victim_vbase + 4);
+}
+
+
+
+/* this function tries to merge the block to free with chunks in the list if they are contiguous
+ * the block can be merged two times.
+ */
+
+void update_chunk_list(unsigned int block_base, unsigned int block_length) {
+    int task_id = giet_global_task_id();
+    /* entire heap is allocated : create a new block of size block_length and give it to the head  */
+    if (_heap_head[task_id] == 0x0) {
+        ((heap_ll *) block_base)->chunk_length = block_length;
+        ((heap_ll *) block_base)->next = 0x0;
+        _heap_head[task_id] = ((heap_ll *) block_base);
+
+        giet_printf("****** NEW BLOCK ******\n"
+                "@ : %x\n"
+                "Length : %d o\n"
+                "***********************\n",
+                block_base,
+                (unsigned int) (((heap_ll *) block_base)->chunk_length));
+        return;
+    }
+
+    /* Test for each Chunk in my list if the block can be merged with */
+    heap_ll * ptr_to_chunk_list = _heap_head[task_id]; // move through the list
+    heap_ll * prev = 0x0; // pointer on the previous visited chunk in the list
+    heap_ll * prev_block_base = 0x0; // pointer on the previous chunk of the chunk that contains the merged block in the list
+    unsigned int chunk_length;
+    int block_merged = 0; // =1 when the block has already been merged with a chunk in the list
+    while (ptr_to_chunk_list != 0x0) {
+        chunk_length = ptr_to_chunk_list->chunk_length;
+        /*  [.....|ptr|block|.....] */
+        if ((unsigned int) (ptr_to_chunk_list) + chunk_length == block_base) {
+
+            giet_printf("****** BLOCK MERGED ******\n"
+                    "CHUNK : %x of size %d o\n"
+                    "merged with \n"
+                    "BLOCK : %x of size %d o\n"
+                    "***********************\n",
+                    (unsigned int) ptr_to_chunk_list,
+                    ptr_to_chunk_list->chunk_length, block_base,
+                    block_length);
+            if (_prev_next_last_allocted[task_id] == ptr_to_chunk_list) {
+                _prev_next_last_allocted[task_id] = ptr_to_chunk_list->next;
+            }
+
+            /* update the size */
+            ptr_to_chunk_list->chunk_length = chunk_length + block_length;
+
+            /* [.....|ptr|[block|old_ptr]|.....]
+             *  remove ptr from the list
+             *  update next pointer
+             *  update the previous chunk of block base to point to ptr
+             */
+            if (block_merged == 1) {
+                prev->next = ptr_to_chunk_list->next;
+                ptr_to_chunk_list->next = ((heap_ll *) block_base)->next;
+
+                if (prev_block_base != 0x0) {
+                    prev_block_base->next = ptr_to_chunk_list;
+                }
+                else {
+                    _heap_head[task_id] = ptr_to_chunk_list;
+                }
+            }
+            /****** for next turn ******/
+            block_base = (unsigned int) ptr_to_chunk_list;
+            block_length = ptr_to_chunk_list->chunk_length;
+
+            giet_printf("****** NEW BLOCK ******\n"
+                    "@ : %x\n"
+                    "Length : %d o\n"
+                    "***********************\n",
+                    (unsigned int) ptr_to_chunk_list,
+                    (unsigned int) (ptr_to_chunk_list->chunk_length));
+            prev_block_base = prev;
+            prev = ptr_to_chunk_list;
+            ptr_to_chunk_list = ptr_to_chunk_list->next;
+            block_merged = 1;
+            continue;
+
+        } // end [.....|ptr|block|.....]
+        /*  [......|block|ptr|.....] */
+        if (block_base + block_length == (unsigned int) ptr_to_chunk_list) {
+
+            giet_printf("****** BLOCK MERGED ******\n"
+                    "BLOCK : %x of size %d o\n"
+                    "merged with \n"
+                    "CHUNK : %x of size %d o\n"
+                    "***********************\n",
+                    block_base, block_length,
+                    (unsigned int) ptr_to_chunk_list,
+                    ptr_to_chunk_list->chunk_length);
+
+            if (_prev_next_last_allocted[task_id] == ptr_to_chunk_list) {
+                _prev_next_last_allocted[task_id] = ptr_to_chunk_list->next;
+            }
+
+            /* update the size */
+            ((heap_ll *) block_base)->chunk_length = block_length + chunk_length;
+
+            /* [.....|block|ptr|......] */
+            if (block_merged == 0) {
+                /* update next pointer
+                 *  update the previous chunk of ptr to point to block_base
+                 */
+                ((heap_ll *) block_base)->next = ptr_to_chunk_list->next;
+                if (prev == 0x0) {
+                    _heap_head[task_id] = ((heap_ll *) block_base);
+                }
+                else {
+                    prev->next = ((heap_ll *) block_base);
+                }
+            }
+            /* [.....[old_ptr|block]|ptr|......] */
+            else {
+                /* remove ptr from the list */
+                prev->next = ptr_to_chunk_list->next;
+                if (prev_block_base != 0x0) {
+                    prev_block_base->next = ((heap_ll *)block_base);
+                }
+                else {
+                    _heap_head[task_id] = ((heap_ll *)block_base);
+                }
+            }
+
+            ptr_to_chunk_list = ((heap_ll *) block_base);
+            block_length = ptr_to_chunk_list->chunk_length;
+
+            giet_printf("****** NEW BLOCK ******\n"
+                    "@ : %x\n"
+                    "Length : %d o\n"
+                    "***********************\n",
+                    (unsigned int) ptr_to_chunk_list,
+                    (unsigned int) (ptr_to_chunk_list->chunk_length));
+            prev_block_base = prev;
+            block_merged = 1;
+        } // end [......|block|ptr|.....]
+
+        prev = ptr_to_chunk_list;
+        ptr_to_chunk_list = ptr_to_chunk_list->next;
+    } // end while
+
+    if (block_merged == 1) {
+        return;
+    }
+
+    /* if the block cant be merge
+     *  create new block and add it to the end of the list 
+     */
+    ((heap_ll *) block_base)->chunk_length = block_length;
+    ((heap_ll *) block_base)->next = 0x0;
+    prev->next = ((heap_ll *) block_base);
+
+
+    giet_printf("****** NEW BLOCK ******\n"
+            "@ : %x\n"
+            "Length : %d o\n"
+            "***********************\n",
+            block_base,
+            (unsigned int) (((heap_ll *) block_base)->chunk_length));
+    return;
+}
+
+
+
+/*########################################################################*/
+/**************************************************************************/
+/**********                 END NEXT-FIT                        ***********/
+/**************************************************************************/
+/*########################################################################*/
+
+#else // Default case : New Fit
+
+/*########################################################################*/
+/**************************************************************************/
+/**********                    CLOSE-FIT                        ***********/
+/**************************************************************************/
+/*########################################################################*/
+
+
+int get_prev_fit_chunk(unsigned int size) {
+    int task_id = giet_global_task_id();
+    int check_remote_free_list = 0;
+    int index;
+after_remote_list_check_c : //c for close fit
+    index = GET_TAB_INDEX(size);
+    while (index != MAX_SIZE_POW2_TAB) {
+        if (_pow2tab[task_id][index] != 0x0) {
+            return index;
+        }
+        index++;
+    }
+
+    if(check_remote_free_list == 0)
+    {
+        heap_ll * poped_block;
+        heap_ll * head_of_rf;
+        check_remote_free_list = 1;
+
+        head_of_rf = pop_ptr();
+
+        while((poped_block = pop_remote_free_list(&head_of_rf)) != 0x0)
+        {
+            update_chunk_list((unsigned int)poped_block, poped_block->chunk_length);
+        }
+        goto after_remote_list_check_c; 
+    }
+
+    return -1;
+}
+
+
+
+void * malloc(unsigned int size) {
+    int task_id = giet_global_task_id();
+
+    giet_printf("############ MALLOC ############\n\n");
+    if(size == 0) {
+
+        giet_printf(" SIZE = 0 \n");
+        return 0x0;
+    }
+    if (size > 0x20000000) {
+
+        giet_printf("ERROR max size = %d\n",0x20000000); 
+        return 0x0;
+    }
+    if (size < 8) {
+        size = 8;
+    }
+
+    /****** First call to malloc ******/
+    if (_first_malloc[task_id] == 0) {
+        giet_heap_info(&_heap_base[task_id], &_heap_length[task_id]);
+
+        if (_heap_length[task_id] == 0) {
+            giet_printf("*** Error: Malloc called in task %d while no heap was defined.\n", task_id);
+            return 0x0;
+        }
+
+        int index = GET_TAB_INDEX(_heap_length[task_id]);
+
+        _pow2tab[task_id][index] = (heap_ll *) _heap_base[task_id];
+        _pow2tab[task_id][index]->chunk_length = _heap_length[task_id];
+        _pow2tab[task_id][index]->next = 0x0;
+
+        *((unsigned int *) ((_heap_base[task_id] +_heap_length[task_id]) - 4))     = _heap_length[task_id];
+
+        _first_malloc[task_id] = 1;
+    }
+
+    /****** Size align ******/
+    int size_align = size;
+    if (size % 4 != 0) {
+        size_align = ((size / 4) + 1) * 4;
+    }
+
+
+    giet_printf("Looking for size : %d %d = %d\n", size_align, 4,size_align+4);
+
+
+    /****** Get tab index of the victim from the chunks list ******/
+    heap_ll * victim;
+    int index;
+    if ((index = get_prev_fit_chunk(size_align + 4)) == -1) {
+        return 0x0;
+    }
+    victim = _pow2tab[task_id][index];
+
+    /****** Get Victim Base ******/
+    unsigned int victim_vbase = (unsigned int) victim;	// overhead
+
+
+    /****** update the chunks list ******/
+    _pow2tab[task_id][index] = _pow2tab[task_id][index]->next;
+
+    if ((victim->chunk_length - (size_align + 4)) < 12) {
+        size_align = size_align + (victim->chunk_length - (size_align + 4)); 
+    } 
+    else {
+        // if its not an exact match then update chunk base and length
+        unsigned int new_size = victim->chunk_length - (size_align + 4); // get the new size;
+        unsigned int new_index = GET_TAB_INDEX(new_size);                 // get the new index;
+        heap_ll * new_chunk = (heap_ll *) (((unsigned int) victim) + (size_align + 4)); //update new_chunk @
+        new_chunk->chunk_length = new_size;                                // write new size
+        *((unsigned int *) ((unsigned int) new_chunk + new_size - 4)) = new_size;                                // on both side of the block
+        new_chunk->next = _pow2tab[task_id][new_index];                     // insert new_chunk @ the new index
+        _pow2tab[task_id][new_index] = new_chunk;
+
+
+        giet_printf("NEXT CHUNK is at @ : 0x%x + 0x%x = 0x%x : @ of size over the block : %x\n",
+                (unsigned int) victim,
+                (unsigned int) ((size_align + 4) / 4),
+                (unsigned int) new_chunk,
+                ((unsigned int) new_chunk + new_chunk->chunk_length) - 4);
+    }
+
+    /****** Write Overhead ******/
+    *((unsigned int *) victim_vbase) = size_align;	// writing overhead on the first word
+
+    giet_printf("BLOCK SUCCESSFULLY ALLOCATED at @ 0x%x user will write at @ 0x%x\n\n",\
+            (unsigned int)(victim_vbase), (unsigned int ) (victim_vbase + 4));
+
+    return (unsigned int *) (victim_vbase + 4);
+}
+
+
+
+/* this function tries to merge the block to free with chunks in the list if they are contiguous
+ * the block can be merged two times.
+ */
+void update_chunk_list(unsigned int block_base, unsigned int block_length) {
+    int task_id = giet_global_task_id();
+
+    int left_merging               = 0;
+    unsigned int left_block_size   = 0;
+    unsigned int left_block_index  = 0;
+    heap_ll * left_block_addr      = 0x0;
+
+    int right_merging              = 0;
+    unsigned int right_block_size  = 0; 
+    unsigned int right_block_index = 0;
+    heap_ll * right_block_addr     = 0x0;
+
+    if (block_base - 4 >= _heap_base[task_id]) {
+
+
+        giet_printf("############# LEFT MERGE #############\n\n");
+        left_block_size = *((unsigned int *) (block_base - 4));
+        left_block_index = GET_TAB_INDEX(left_block_size);
+        left_block_addr = (heap_ll *)(block_base - left_block_size);
+        left_merging = 1;
+    }
+
+    if ((block_base + block_length) <= (_heap_base[task_id] + _heap_length[task_id]) - 8) {
+
+        giet_printf("############# RIGHT MERGE #############\n\n");
+        right_block_size = ((heap_ll *)(block_base + block_length))->chunk_length;
+        right_block_index = GET_TAB_INDEX(right_block_size);
+        right_block_addr = (heap_ll *) (block_base + block_length);
+        right_merging = 1;
+    }
+
+
+    giet_printf("############# END PREP MERGE #############\n\n");
+
+    heap_ll * ptr_to_chunk = 0x0;
+    heap_ll * prev_ptr_to_chunk = 0x0;
+
+    heap_ll * ptr_to_chunk_right = 0x0;
+    heap_ll * prev_ptr_to_chunk_right = 0x0;
+
+    unsigned int new_size = block_length;
+    unsigned int new_index = 0;
+    int merged_left = 0;
+    heap_ll * new_addr = 0x0;
+
+
+
+    /* try to merge with left block */
+    if (left_merging == 1 &&
+            (unsigned int) left_block_addr >= _heap_base[task_id] &&
+            (unsigned int) left_block_addr <= block_base - 12) {
+        ptr_to_chunk = _pow2tab[task_id][left_block_index];
+        while (ptr_to_chunk != 0x0) {
+            if (ptr_to_chunk == left_block_addr && ptr_to_chunk->chunk_length == left_block_size) {
+                new_size = new_size + left_block_size;
+                if (prev_ptr_to_chunk == 0x0) {
+                    _pow2tab[task_id][left_block_index] = ptr_to_chunk->next;
+                }
+                else {
+                    prev_ptr_to_chunk->next = ptr_to_chunk->next;
+                }
+                merged_left = 1;
+                break;
+            }
+            else if (ptr_to_chunk == right_block_addr && ptr_to_chunk->chunk_length == right_block_size) {
+                ptr_to_chunk_right = ptr_to_chunk;
+                prev_ptr_to_chunk_right = prev_ptr_to_chunk;
+            }
+            prev_ptr_to_chunk = ptr_to_chunk;
+            ptr_to_chunk = ptr_to_chunk->next;
+        }
+    }
+
+    if (right_block_index != left_block_index) {
+        prev_ptr_to_chunk = 0x0;
+        ptr_to_chunk = _pow2tab[task_id][right_block_index];
+    }
+    else {
+        ptr_to_chunk = ptr_to_chunk_right;
+        prev_ptr_to_chunk = prev_ptr_to_chunk_right;
+    }
+
+    /* try to merge with right block */
+    if (right_merging == 1 &&
+            (unsigned int) right_block_addr >= block_base + block_length &&
+            (unsigned int) right_block_addr <= (_heap_base[task_id] + _heap_length[task_id]) - 12) {
+        while (ptr_to_chunk != 0x0) {
+            if (ptr_to_chunk == right_block_addr && ptr_to_chunk->chunk_length == right_block_size) {
+                new_size = new_size + right_block_size;
+                if (prev_ptr_to_chunk == 0x0) {
+                    _pow2tab[task_id][right_block_index] = ptr_to_chunk->next;
+                }
+                else {
+                    prev_ptr_to_chunk->next = ptr_to_chunk->next;
+                }
+                break;
+            }
+            prev_ptr_to_chunk = ptr_to_chunk;
+            ptr_to_chunk = ptr_to_chunk->next;
+        }
+    }
+    new_index = GET_TAB_INDEX(new_size);
+    if (merged_left == 1) {
+        new_addr = (heap_ll *) (block_base - left_block_size);
+    }
+    else {
+        new_addr = (heap_ll *) block_base;
+    }
+    new_addr->chunk_length = new_size;
+    *((unsigned int *) ((unsigned int) new_addr + (new_addr->chunk_length - 4))) = new_size;
+    new_addr->next = _pow2tab[task_id][new_index];
+    _pow2tab[task_id][new_index] = new_addr;
+
+    giet_printf("########################  UPDT SUCCESS ######################\n");
+
+    return;
+}
+
+
+
+
+/*########################################################################*/
+/**************************************************************************/
+/**********                 END CLOSE-FIT                       ***********/
+/**************************************************************************/
+/*########################################################################*/
+
+#endif // New Fit
+
+heap_ll * pop_remote_free_list(heap_ll ** head)
+{
+
+    heap_ll * poped_block;
+
+    if (*head == 0x0)
+    {
+        giet_printf(" no block to pop\n");
+        return 0x0;
+    }
+    else
+    {
+        poped_block = *head;
+        *head = (*head)->next;
+
+        giet_printf(" : @%x, size : %x\n", poped_block, poped_block->chunk_length);
+    }
+
+    return poped_block;
+}
+
+heap_ll * pop_ptr(void)
+{
+    int task_id = giet_global_task_id();
+    heap_ll * head_of_rf_list;
+    giet_printf(" -- POP lock acquire -- for %d : @ : %x\n", task_id, &lock_rf_list[task_id]);
+    lock_acquire(&lock_rf_list[task_id]);
+    giet_printf(" -- POP lock acquired --\n");
+
+    head_of_rf_list = _remote_free_list[task_id];
+    _remote_free_list[task_id] = 0x0;
+
+    lock_release(&lock_rf_list[task_id]);
+    return head_of_rf_list;
+
+}
+
+void insert_in_remote_free_list(unsigned int remote_owner_id, unsigned int block_base, unsigned int block_length)
+{
+
+    giet_printf("############### INSERT \n");
+    ((heap_ll *)block_base)->chunk_length = block_length;
+
+    giet_printf(" -- INSERT lock acquire -- for %d : @ : %x\n", remote_owner_id, &lock_rf_list[remote_owner_id]);
+    lock_acquire(&lock_rf_list[remote_owner_id]);
+
+    giet_printf(" -- INSERT lock acquired -- \n");
+
+    // insertion en dÃ©but de liste
+    giet_printf("  in remote_owner %d ...\n", remote_owner_id);
+    if (_remote_free_list[remote_owner_id] == 0x0)
+    {
+        ((heap_ll *)block_base)->next = 0x0;
+    } 
+    else
+    {
+        ((heap_ll *)block_base)->next = _remote_free_list[remote_owner_id];
+    }
+    _remote_free_list[remote_owner_id] = ((heap_ll *)block_base);
+
+    giet_printf("  : OK\n\n");
+    giet_printf(" new head : %x : of size : %x, with next : %x\n", _remote_free_list[remote_owner_id], _remote_free_list[remote_owner_id]->chunk_length, _remote_free_list[remote_owner_id]->next);
+
+    lock_release(&lock_rf_list[remote_owner_id]);
+
+    return;
+}
+
+void free(void * ptr) {
+    int i = 0;
+    while (i != NB_TASKS_MAX)
+    {
+        if( _heap_base[i] == -1)
+        {
+            continue;
+        }
+        if ((unsigned int)ptr > _heap_base[i] && (unsigned int)ptr < _heap_base[i] + _heap_length[i])
+        {
+            break;
+        }
+        i++;
+    }
+
+    int task_id = giet_global_task_id();
+    unsigned int * to_free = ptr;
+    unsigned int heapB;
+    unsigned int heapL;
+    unsigned int overhead;
+    unsigned int block_base;
+    unsigned int block_length;
+    unsigned int remote_free_needed;
+    unsigned int remote_owner_id;
+    if (i == task_id)
+    {
+
+        giet_printf("############# FREE  #############\n\n");
+        remote_free_needed = 0;
+        remote_owner_id = -1;
+        heapB = _heap_base[task_id];
+        heapL = _heap_length[task_id];
+    }
+    else
+    {
+
+        giet_printf("############# REMOTE FREE  #############\n\n");
+        remote_free_needed = 1;
+        remote_owner_id = i;
+        heapB = _heap_base[remote_owner_id];
+        heapL = _heap_length[remote_owner_id];
+    }
+
+
+    /****** CHECK PTR ******/
+    if (to_free == 0x0) {
+
+        giet_printf("free == 0x0\n");
+        return;
+    }
+    // check alignement of ptr
+    if (((unsigned int) to_free) % 4 != 0) {
+
+        giet_printf("allignement of ptr  %x = %d\n", (unsigned int) to_free, (unsigned int) to_free % 4);
+        return;
+    }
+    // check if the @ of ptr matches the range of the heap
+    if (!((unsigned int) to_free >= heapB && (unsigned int) to_free < heapB + heapL)) {
+
+        giet_printf("check if it matches the range of the heap\n");
+        return;
+    }
+
+    // get the 4 bytes before the ptr that contains the size of the block 
+    overhead = *(to_free - 1);
+    // check alignement of overhead
+    if (overhead % 4 != 0) {
+
+        giet_printf("check alignement of overhead\n");
+        return;
+    }
+    // check if (overhead + to_free) matches the range of the heap
+    if ((((unsigned int) (to_free) + overhead) - 4) > heapB + heapL) {
+
+        giet_printf ("check if (overhead + to_free) matches the range of the heap\n");
+        return;
+    }
+
+    block_base = (unsigned int) (to_free - 1);
+    block_length = overhead + 4;
+
+    if (remote_free_needed == 0)
+    {
+
+        giet_printf("############# UPDATE CL :  FREE %x of size %d #############\n\n",block_base, block_length);
+        update_chunk_list(block_base, block_length);
+    }
+    else
+    {
+
+        giet_printf("############# INSERT IN RF %d :  FREE %x of size %d #############\n\n", remote_owner_id, block_base, block_length);
+        insert_in_remote_free_list(remote_owner_id, block_base, block_length);
+    }
+
+
+    giet_printf("BLOCK SUCCESSFULLY FREED\n\n");
+
+    return;
+}
+
+
+
+
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
+
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/malloc.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/malloc.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/malloc.h	(revision 283)
@@ -0,0 +1,30 @@
+////////////////////////////////////////////////////////////////////////////
+// File     : malloc.h
+// Date     : 05/03/2013
+// Author   : Jean-Baptiste BrÃ©jon
+// Copyright (c) UPMC-LIP6
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MALLOC_H_
+#define _MALLOC_H_
+//#define DEBUG_MALLOC 1
+
+#include "giet_config.h"
+#include "spin_lock.h"
+
+//#define MALLOC_SELECTED 2
+
+void * malloc(unsigned int size);
+void free(void * ptr);
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/malloc_private.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/malloc_private.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/malloc_private.h	(revision 283)
@@ -0,0 +1,38 @@
+////////////////////////////////////////////////////////////////////////////
+// File     : malloc_private.h
+// Date     : 05/03/2013
+// Author   : Jean-Baptiste BrÃ©jon
+// Copyright (c) UPMC-LIP6
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MALLOC_PRIVATE_H_
+#define _MALLOC_PRIVATE_H_
+
+
+typedef struct heap_linked_list {
+    struct heap_linked_list * next;
+    unsigned int chunk_length;
+} heap_ll;
+
+void insert_in_remote_free_list(unsigned int remote_owner_id, unsigned int block_base, unsigned int block_length);
+heap_ll * pop_remote_free_list(heap_ll ** head);
+heap_ll * pop_ptr(void);
+void update_chunk_list(unsigned int block_base, unsigned int block_length);
+
+#if MALLOC_SELECTED == 1 || MALLOC_SELECTED == 2
+    static heap_ll * get_prev_fit_chunk(unsigned int size);
+#else
+    int get_prev_fit_chunk(unsigned int size);
+#endif
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/memspace.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/memspace.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/memspace.h	(revision 283)
@@ -0,0 +1,23 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : memspace.h         
+// Date     : 12/02/2013
+// Author   : Quentin Meunier
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MEMSPACE_H_
+#define _MEMSPACE_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+//  memspace structure
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct _giet_memspace_s 
+{
+    void * buffer;
+    unsigned int size;
+} giet_memspace_t;
+
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/mwmr_channel.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/mwmr_channel.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/mwmr_channel.c	(revision 283)
@@ -0,0 +1,372 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : mwmr_channel_.c         
+// Date     : 01/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The mwmr_channel.c and mwmr_channel.h files are part of the GIET nano-kernel.
+// This  middleware implements a user level Multi-Writers / Multi-Readers
+// communication channel, that can be used by parallel multi-tasks applications
+// respecting the TCG (Tasks and Communications Graph) formalism.
+// 
+// The mwmr_read() and mwmr_write() functions do not require a system call.
+// The channel itself must have been allocated in a non cacheable segment,
+// if the platform does not provide hardware cache coherence.
+//
+// ALL MWMR channels must be defined in the mapping_info data structure, 
+// to be initialised by the GIET in the boot phase.
+// The vobj_get_vbase() system call (defined in stdio.c and stdio.h files)
+// can be used to get the virtual base address of the channel from it's name.
+//
+// An MWMR transaction transfer    an integer number of items, and an item is
+// an integer number of unsigned int (32 bits words).
+// The max number of words that can be stored in a MWMR channel is defined by the
+// "depth" parameter, and the "width" parameter define the minimal number of
+// word contained in an atomic item. Therefore, the "depth" parameter must be
+// a multiple of the "width" parameter.
+//
+// Both the mwmr_read() and mwmr_write() functions are blocking functions. 
+// A private lock provides exclusive access to the MWMR channel, that can have
+// a variable number of producers and a variable number of consumers.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <mwmr_channel.h>
+#include <stdio.h>
+
+//////////////////////////////////////////////////////////////////////////////
+//  mwmr_lock_aquire()
+// This blocking function returns only when the lock has been taken.
+// If the lock is already taken a fixed delay is introduced before retry.
+//////////////////////////////////////////////////////////////////////////////
+void mwmr_lock_acquire(unsigned int * lock_address) {
+    register unsigned int * plock = lock_address;
+    register unsigned int delay = 100;
+    asm volatile (
+            "mwmr_lock_try:                    \n"
+            "ll   $2,    0(%0)                \n" /* $2 <= lock current value */
+            "bnez $2,    mwmr_lock_delay    \n" /* retry after delay if lock busy */
+            "li   $3,    1                    \n" /* $3 <= argument for sc */
+            "sc   $3,    0(%0)                \n" /* try to get lock */
+            "bnez $3,    mwmr_lock_ok        \n" /* exit if atomic */
+            "mwmr_lock_delay:                \n"
+            "move $4,    %1                 \n" /* $4 <= delay */
+            "mwmr_lock_loop:                \n"
+            "beqz $4,    mwmr_lock_loop        \n" /* test end delay */
+            "addi $4,    $4,  -1            \n" /* $4 <= $4 - 1 */
+            "j           mwmr_lock_try        \n" /* retry ll */
+            "nop                            \n"
+            "mwmr_lock_ok:                    \n"
+            :
+            :"r"(plock), "r"(delay)
+            :"$2", "$3", "$4");
+} 
+
+
+//////////////////////////////////////////////////////////////////////////////
+//       nb_mwmr_write()
+// This is a non-blocking function.
+// The nitems parameter is the number of items to be transfered.
+// The requested transfer is therefore (nitems * width) words.
+// It takes the lock for exclusive access before testing the channel state.
+// If there is not enough data in mwmr channel to read nitems,
+// it reads as many items as possible, releases the lock, and returns 
+// the number of read items (it can be 0).
+//////////////////////////////////////////////////////////////////////////////
+unsigned int nb_mwmr_write(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
+    unsigned int x;
+    unsigned int spaces; // number of empty slots (in words)
+    unsigned int nwords; // requested transfer length (in words)
+    unsigned int depth;  // channel depth (in words)
+    unsigned int width;  // channel width (in words)
+    unsigned int sts;    // channel sts
+    unsigned int ptw;    // channel ptw
+
+    if (nitems == 0) {
+        return 0;
+    }
+
+    // get the lock
+    mwmr_lock_acquire(&mwmr->lock);
+
+    // access fifo status
+    depth = mwmr->depth;
+    width = mwmr->width;
+    sts = mwmr->sts;
+    ptw = mwmr->ptw;
+    spaces = depth - sts;
+    nwords = width * nitems;
+
+    if (spaces >= nwords) { // transfer nitems, release lock and return 
+        for (x = 0; x < nwords; x++) {
+            mwmr->data[ptw] = buffer[x];
+            if ((ptw + 1) == depth) {
+                ptw = 0;
+            }
+            else {
+                ptw = ptw + 1;
+            }
+        }
+        mwmr->sts = mwmr->sts + nwords;
+        mwmr->ptw = ptw;
+        mwmr->lock = 0;
+        return nitems;
+    }
+    else if (spaces < width) {
+        // release lock and return 
+        mwmr->lock = 0;
+        return 0;
+    }
+    else {
+        // transfer as many items as possible, release lock and return 
+        nwords = (spaces / width) * width;    // integer number of items
+        for (x = 0; x < nwords; x++) {
+            mwmr->data[ptw] = buffer[x];
+            if ((ptw + 1) == depth) {
+                ptw = 0;
+            }
+            else {
+                ptw = ptw + 1;
+            }
+        }
+        mwmr->sts = sts + nwords;
+        mwmr->ptw = ptw;
+        mwmr->lock = 0;
+        return (nwords / width);
+    }
+} // end nb_mwmr_write()
+
+
+//////////////////////////////////////////////////////////////////////////////
+//    mwmr_write()
+// This blocking function returns only when the transfer is completed.
+// The nitems parameter is the number of items to be transfered.
+// The requested transfer is therefore (nitems * width) words.
+// It takes the lock for exclusive access before testing the channel state.
+// If there is not enough space in mwmr channel to write nitems,
+// it writes as many items as possible, releases the lock, and retry 
+// after a random delay.
+//////////////////////////////////////////////////////////////////////////////
+void mwmr_write(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
+    unsigned int x;
+    unsigned int spaces; // number of empty slots (in words)
+    unsigned int nwords; // requested transfer length (in words)
+    unsigned int depth;  // channel depth (in words)
+    unsigned int width;  // channel width (in words)
+    unsigned int sts;    // channel sts
+    unsigned int ptw;    // channel ptw
+
+    if (nitems == 0) {
+        return;
+    }
+
+    while (1) {
+        // get the lock
+        mwmr_lock_acquire(&mwmr->lock);
+
+        // compute spaces and nwords
+        depth = mwmr->depth;
+        width = mwmr->width;
+        sts  = mwmr->sts;
+        ptw  = mwmr->ptw;
+        spaces = depth - sts;
+        nwords = width * nitems;
+
+        if (spaces >= nwords) {
+            // write nwords, release lock and return
+            for (x = 0; x < nwords; x++) {
+                mwmr->data[ptw] = buffer[x];
+                if ((ptw + 1) == depth) {
+                    ptw = 0;
+                }
+                else {
+                    ptw = ptw + 1;
+                }
+            }
+            mwmr->ptw = ptw;
+            mwmr->sts = sts + nwords;
+            mwmr->lock = 0;
+            return;
+        }
+        else if (spaces < width) {
+            // release lock and retry after delay
+            mwmr->lock = 0;
+        }
+        else {
+            // write as many items as possible, release lock and retry after delay
+            nwords = (spaces / width) * width;  // integer number of items
+            for (x = 0; x < nwords; x++) {
+                mwmr->data[ptw] = buffer[x];
+                if ((ptw + 1) == depth) {
+                    ptw = 0;
+                }
+                else {
+                    ptw = ptw + 1;
+                }
+            }
+            mwmr->sts = sts + nwords;
+            mwmr->ptw = ptw;
+            buffer = buffer + nwords;
+            nitems = nitems - (nwords/width);
+            mwmr->lock = 0;
+        }
+        giet_context_switch();
+    }
+} // end mwmr_write()
+
+
+//////////////////////////////////////////////////////////////////////////////
+//       nb_mwmr_read()
+// This is a non-blocking function.
+// The nitems parameter is the number of items to be transfered.
+// The requested transfer is therefore (nitems * width) words.
+// It takes the lock for exclusive access before testing the channel state.
+// If there is not enough data in mwmr channel to read nitems,
+// it reads as many items as possible, releases the lock, and returns 
+// the number of read items (it can be 0).
+//////////////////////////////////////////////////////////////////////////////
+unsigned int nb_mwmr_read(mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
+    unsigned int x;
+    unsigned int nwords; // requested transfer length (in words)
+    unsigned int depth;  // channel depth (in words)
+    unsigned int width;  // channel width (in words)
+    unsigned int sts;    // channel sts
+    unsigned int ptr;    // channel ptr
+
+    if (nitems == 0) {
+        return 0;
+    }
+
+    // get the lock
+    mwmr_lock_acquire(&mwmr->lock);
+
+    // access fifo status
+    depth = mwmr->depth;
+    width = mwmr->width;
+    sts = mwmr->sts;
+    ptr = mwmr->ptr;
+    nwords = width * nitems;
+
+    if (sts >= nwords) {
+        // transfer nitems, release lock and return 
+        for (x = 0; x < nwords; x++) {
+            buffer[x] = mwmr->data[ptr];
+            if ((ptr + 1) == depth) {
+                ptr = 0;
+            }
+            else {
+                ptr = ptr + 1;
+            }
+        }
+        mwmr->sts = mwmr->sts - nwords;
+        mwmr->ptr = ptr;
+        mwmr->lock = 0;
+        return nitems;
+    }
+    else if (sts < width) {
+        // release lock and return 
+        mwmr->lock = 0;
+        return 0;
+    }
+    else {
+        // transfer as many items as possible, release lock and return 
+        nwords = (sts / width) * width; // integer number of items
+        for (x = 0 ; x < nwords ; x++) {
+            buffer[x] = mwmr->data[ptr];
+            if ((ptr + 1) == depth) {
+                ptr = 0;
+            }
+            else {
+                ptr = ptr + 1;
+            }
+        }
+        mwmr->sts = sts - nwords;
+        mwmr->ptr = ptr;
+        mwmr->lock = 0;
+        return (nwords / width);
+    }
+} // nb_mwmr_read()
+
+
+//////////////////////////////////////////////////////////////////////////////
+//    mwmr_read()
+// This blocking function returns only when the transfer is completed.
+// The nitems parameter is the number of items to be transfered.
+// The requested transfer is therefore (nitems * width) words.
+// It takes the lock for exclusive access before testing the channel state.
+// If there is not enough data in mwmr channel to read nitems,
+// it reads as many items as possible, releases the lock, and retry 
+// after a random delay.
+//////////////////////////////////////////////////////////////////////////////
+void mwmr_read( mwmr_channel_t * mwmr, unsigned int * buffer, unsigned int nitems) {
+    unsigned int x;
+    unsigned int nwords; // requested transfer length (in words)
+    unsigned int depth;  // channel depth (in words)
+    unsigned int width;  // channel width (in words)
+    unsigned int sts;    // channel sts
+    unsigned int ptr;    // channel ptr
+
+    if (nitems == 0) {
+        return;
+    }
+
+    while (1) {
+        // get the lock
+        mwmr_lock_acquire(&mwmr->lock);
+
+        // compute nwords
+        depth = mwmr->depth;
+        width = mwmr->width;
+        sts = mwmr->sts;
+        ptr = mwmr->ptr;
+        nwords = width * nitems;
+
+        if (sts >= nwords) {
+            // read nwords, release lock and return
+            for (x = 0; x < nwords; x++) {
+                buffer[x] = mwmr->data[ptr];
+                if ((ptr + 1) == depth) {
+                    ptr = 0;
+                }
+                else {
+                    ptr = ptr + 1;
+                }
+            }
+            mwmr->sts = mwmr->sts - nwords;
+            mwmr->ptr = ptr;
+            mwmr->lock = 0;
+            return;
+        }
+        else if (sts < width) {
+            // release lock and retry after delay
+            mwmr->lock = 0;
+        }
+        else {   // read as many items as possible, release lock and retry after delay
+            nwords = (sts / width) * width; // integer number of items
+            for (x = 0; x < nwords; x++) {
+                buffer[x] = mwmr->data[ptr];
+                if ((ptr + 1) == depth) {
+                    ptr = 0;
+                }
+                else {
+                    ptr = ptr + 1;
+                }
+            }
+            mwmr->sts = sts - nwords;
+            mwmr->ptr = ptr;
+            buffer = buffer + nwords;
+            nitems = nitems - (nwords/width);
+            mwmr->lock = 0;
+        }
+        giet_context_switch();
+    }
+} // end mwmr_read() 
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/mwmr_channel.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/mwmr_channel.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/mwmr_channel.h	(revision 283)
@@ -0,0 +1,58 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : mwmr_channel.h         
+// Date     : 01/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MWMR_CHANNEL_H_
+#define _MWMR_CHANNEL_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+//  MWMR channel structure
+// The data array size is defined to obtain sizeof(mwmr_channel_t) = 4096 bytes.
+// The actual size can be redefined in the mapping info data structure.
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct mwmr_channel_s 
+{
+    unsigned int ptr;        // index of the first valid data word
+    unsigned int ptw;        // index of the first empty slot 
+    unsigned int sts;        // number of words available
+    unsigned int lock;       // exclusive access lock
+    unsigned int depth;      // max number of words in the channel
+    unsigned int width;      // number of words in an item      
+    unsigned int data[1018]; // circular buffer
+} mwmr_channel_t;
+
+//////////////////////////////////////////////////////////////////////////////
+//  MWMR access functions
+//////////////////////////////////////////////////////////////////////////////
+
+void mwmr_write( mwmr_channel_t* mwmr, 
+                 unsigned int*   buffer, 
+                 unsigned int    nitems );
+
+void mwmr_read(  mwmr_channel_t* mwmr, 
+                 unsigned int*   buffer, 
+                 unsigned int    nitems );
+
+unsigned int nb_mwmr_read ( mwmr_channel_t * mwmr,
+                            unsigned int * buffer,
+                            unsigned int nitems );
+
+
+unsigned int nb_mwmr_write( mwmr_channel_t * mwmr,
+                            unsigned int * buffer,
+                            unsigned int nitems );
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/spin_lock.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/spin_lock.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/spin_lock.c	(revision 283)
@@ -0,0 +1,79 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : spin_lock.c         
+// Date     : 01/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The spin_lock.c and spin_lock.h files are part of the GIET nano-kernel.
+// This  middlewre implements a user-level lock (busy waiting mechanism,
+// because the GIET does not support task scheduling / descheduling).
+// It is a simple binary lock, without waiting queue.
+// 
+// The lock_acquire() and lock_release() functions do not require a system call.
+// The barrier itself must have been allocated in a non cacheable segment,
+// if the platform does not provide hardwate cache coherence.
+//
+// ALL locks must be defined in the mapping_info data structure, 
+// to be initialised by the GIET in the boot phase.
+// The vobj_get_vbase() system call (defined in stdio.c and stdio.h files)
+// can be used to get the virtual base address of the lock fro it's name.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <spin_lock.h>
+#include <stdio.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+// lock_acquire()
+// This blocking function returns only when the lock has been taken.
+// If the lock is already taken a random delay is introduced before retry.
+///////////////////////////////////////////////////////////////////////////////////
+void lock_acquire(giet_lock_t * lock) {
+    unsigned int * plock = &lock->value;
+    unsigned int delay = giet_rand();
+
+    if (delay == 0) delay++;
+
+    asm volatile (
+            "giet_lock_try:              \n"
+            "ll   $2,    0(%0)           \n" /* $2 <= _ioc_lock current value */
+            "bnez $2,    giet_lock_delay \n" /* delay if _ioc_lock already taken */
+            "li   $3,    1               \n" /* $3 <= argument for sc */
+            "sc   $3,    0(%0)           \n" /* try to set _ioc_lock */
+            "bnez $3,    giet_lock_ok    \n" /* exit if atomic */
+
+            "giet_lock_delay:            \n"
+            "move $4,    %1              \n" /* $4 <= delay */
+
+            "giet_lock_loop:             \n"
+            "addi $4,    $4,    -1       \n" /* $4 <= $4 - 1 */
+            "bnez $4,    giet_lock_loop  \n" /* test end delay */
+            "nop                         \n"
+            "j           giet_lock_try   \n" /* retry */
+            "nop                         \n"
+
+            "giet_lock_ok:               \n"
+            :
+            :"r"(plock), "r"(delay)
+            :"$2", "$3", "$4");
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// lock_release()
+//////////////////////////////////////////////////////////////////////////////
+void lock_release(giet_lock_t * lock) {
+    unsigned int * plock = &lock->value;
+
+    asm volatile ( "sync\n" ); // necessary because of the TSAR consistency model 
+    *plock = 0;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/spin_lock.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/spin_lock.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/spin_lock.h	(revision 283)
@@ -0,0 +1,37 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : spin_lock.h         
+// Date     : 01/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _GIET_SPIN_LOCK_H_
+#define _GIET_SPIN_LOCK_H_
+
+///////////////////////////////////////////////////////////////////////////////////
+//  lock structure
+// This is a simple binary lock (without waiting queue).
+///////////////////////////////////////////////////////////////////////////////////
+
+typedef struct giet_lock_s {
+    char name[32];      // lock name
+    unsigned int value; // taken if value != 0
+} giet_lock_t;
+
+//////////////////////////////////////////////////////////////////////////////
+//  access functions
+//////////////////////////////////////////////////////////////////////////////
+
+void lock_acquire(giet_lock_t * lock);
+void lock_release(giet_lock_t * lock);
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/srl.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/srl.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/srl.h	(revision 283)
@@ -0,0 +1,25 @@
+#ifndef SRL_H_
+#define SRL_H_
+
+/**
+   @file
+   @module{SRL}
+   @short SRL Api main header
+ */
+
+#include "mapping_info.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "libsrl/srl_public_types.h"
+#include "libsrl/srl_lock.h"
+#include "libsrl/srl_mwmr.h"
+#include "libsrl/srl_log.h"
+#include "libsrl/srl_barrier.h"
+#include "libsrl/srl_memspace.h"
+#include "libsrl/srl_hw_helpers.h"
+#include "libsrl/srl_args.h"
+
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/stdio.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/stdio.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/stdio.c	(revision 283)
@@ -0,0 +1,832 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : stdio.c         
+// Date     : 01/04/2010
+// Author   : alain greiner & Joel Porquet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The stdio.c and stdio.h files are part of the GIET_VM nano-kernel.
+// This library contains all user-level functions that contain a system call
+// to access protected or shared ressources.
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <giet_config.h>
+
+////////////////////////////////////////////////////////////////////////////////////
+//////////////////////  MIPS32 related system calls  ///////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// giet_procid()
+////////////////////////////////////////////////////////////////////////////////////
+// This function returns the processor identifier.
+////////////////////////////////////////////////////////////////////////////////////
+int giet_procid() 
+{
+    return sys_call( SYSCALL_PROCID,
+                     0, 0, 0, 0 );
+}
+////////////////////////////////////////////////////////////////////////////////////
+// giet_proctime()
+////////////////////////////////////////////////////////////////////////////////////
+// This function returns the local processor time (clock cycles since boot)
+////////////////////////////////////////////////////////////////////////////////////
+int giet_proctime() 
+{
+    return sys_call( SYSCALL_PROCTIME, 
+                     0, 0, 0, 0 );
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+/////////////////////  TTY device related system calls /////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////
+// giet_tty_putc()
+////////////////////////////////////////////////////////////////////////////////////
+// This function displays a single ascii character on a terminal.
+// The terminal index must be defined in the task context in the boot phase.
+// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
+// - Returns 1 if the character has been written, 0 otherwise.
+////////////////////////////////////////////////////////////////////////////////////
+int giet_tty_putc(char byte) 
+{
+    return sys_call(SYSCALL_TTY_WRITE, 
+                    (unsigned int)(&byte),
+                    1, 
+                    0xFFFFFFFF,  
+                    0);
+}
+////////////////////////////////////////////////////////////////////////////////////
+// giet_tty_puts()
+////////////////////////////////////////////////////////////////////////////////////
+// This function displays a string on a terminal.
+// The terminal index must be defined in the task context in the boot phase.
+// The string must be terminated by a NUL character.
+// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
+// - Returns the number of written characters.
+////////////////////////////////////////////////////////////////////////////////////
+int giet_tty_puts(char * buf) 
+{
+    unsigned int length = 0;
+    while (buf[length] != 0) { length++; }
+    return sys_call(SYSCALL_TTY_WRITE, 
+                   (unsigned int)buf, 
+                   length, 
+                   0xFFFFFFFF, 
+                   0);
+}
+////////////////////////////////////////////////////////////////////////////////////
+// giet_tty_putw()
+////////////////////////////////////////////////////////////////////////////////////
+// This function displays the value of a 32-bit word with decimal characters.
+// The terminal index must be defined in the task context in the boot phase.
+// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
+// Returns the number of written characters (should be equal to ten).
+////////////////////////////////////////////////////////////////////////////////////
+int giet_tty_putw(unsigned int val) 
+{
+    char buf[10];
+    unsigned int i;
+    for (i = 0; i < 10; i++) 
+    {
+        buf[9 - i] = (val % 10) + 0x30;
+        val = val / 10;
+    }
+    return sys_call(SYSCALL_TTY_WRITE, 
+                   (unsigned int)buf,
+                   10,
+                   0xFFFFFFFF,
+                   0);
+}
+////////////////////////////////////////////////////////////////////////////////////
+// giet_tty_getc()
+////////////////////////////////////////////////////////////////////////////////////
+// This blocking function fetches a single ascii character from a terminal.
+// The terminal index must be defined in the task context in the boot phase.
+// It uses the IRQ_GET interrupt, and the associated kernel buffer.
+// - Returns 0 when completed.
+////////////////////////////////////////////////////////////////////////////////////
+int giet_tty_getc(char * byte) 
+{
+    unsigned int ret = 0;
+    while (ret == 0) 
+    {
+        ret = sys_call(SYSCALL_TTY_READ, 
+                      (unsigned int)byte,  // buffer address
+                      1,                   // number of characters
+                      0xFFFFFFFF,          // channel index from task context
+                      0);
+    }
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////
+// giet_tty_gets()
+////////////////////////////////////////////////////////////////////////////////////
+// This blocking function fetches a string from a terminal to a fixed length buffer.
+// The terminal index must be defined in the task context in the boot phase.
+// It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
+// - Returns 0 when completed.
+// - Up to (bufsize - 1) characters (including the non printable characters)
+//   will be copied into buffer, and the string is always completed by a NUL
+//   character.
+// - The <LF> character is interpreted, and the function close the string with a
+//   NUL character if <LF> is read.
+// - The <DEL> character is interpreted, and the corresponding character(s) are
+//   removed from the target buffer.
+////////////////////////////////////////////////////////////////////////////////////
+int giet_tty_gets( char*        buf, 
+                   unsigned int bufsize) 
+{
+    unsigned int ret;
+    unsigned char byte;
+    unsigned int index = 0;
+
+    while (index < (bufsize - 1)) 
+    {
+        do 
+        { 
+            ret = sys_call(SYSCALL_TTY_READ, 
+                           (unsigned int)(&byte),
+                           1,
+                           0xFFFFFFFF,
+                           0);
+        } 
+        while (ret != 1);
+
+        if (byte == 0x0A)  /* LF */
+        {
+            break; 
+        }
+        else if ((byte == 0x7F) && (index > 0))  /* DEL */
+        {
+            index--; 
+        }
+        else 
+        {
+            buf[index] = byte;
+            index++;
+        }
+    }
+    buf[index] = 0;
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////
+// giet_tty_getw()
+////////////////////////////////////////////////////////////////////////////////////
+// This blocking function fetches a string of decimal characters (most
+// significant digit first) to build a 32-bit unsigned integer.
+// The terminal index must be defined in the task context in the boot phase.
+// It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
+// - Returns necessarily 0 when completed.
+//
+// - The non-blocking system function _tty_read_irq is called several times,
+//   and the decimal characters are written in a 32 characters buffer until a
+//   <LF> character is read.
+// - The <DEL> character is interpreted, and previous characters can be
+//   cancelled. All others characters are ignored.
+// - When the <LF> character is received, the string is converted to an
+//   unsigned int value. If the number of decimal digit is too large for the 32
+//   bits range, the zero value is returned.
+////////////////////////////////////////////////////////////////////////////////////
+int giet_tty_getw(unsigned int * val) 
+{
+    unsigned char buf[32];
+    unsigned char byte;
+    unsigned int save = 0;
+    unsigned int dec = 0;
+    unsigned int done = 0;
+    unsigned int overflow = 0;
+    unsigned int max = 0;
+    unsigned int i;
+    unsigned int ret;
+
+    while (done == 0) 
+    {
+        do 
+        { 
+            ret = sys_call(SYSCALL_TTY_READ,
+                           (unsigned int)(&byte),
+                           1,
+                           0xFFFFFFFF,
+                           0); 
+        } 
+        while (ret != 1);
+
+        if ((byte > 0x2F) && (byte < 0x3A))  /* decimal character */
+        {
+            buf[max] = byte;
+            max++;
+            giet_tty_putc(byte);
+        }
+        else if ((byte == 0x0A))   /* LF */
+        {
+            done = 1;
+        }
+        else if (byte == 0x7F)   /* DEL */
+        {
+            if (max > 0) 
+            {
+                max--;      /* cancel the character */
+                giet_tty_putc(0x08);
+                giet_tty_putc(0x20);
+                giet_tty_putc(0x08);
+            }
+        }
+        if (max == 32)  /* decimal string overflow */
+        {
+            for (i = 0; i < max; i++) 
+            {
+                /* cancel the string */
+                giet_tty_putc(0x08);
+                giet_tty_putc(0x20);
+                giet_tty_putc(0x08);
+            }
+            giet_tty_putc(0x30);
+            *val = 0;      /* return 0 value */
+            return 0;
+        }
+    }
+
+    /* string conversion */
+    for (i = 0; i < max; i++) 
+    {
+        dec = dec * 10 + (buf[i] - 0x30);
+        if (dec < save)  overflow = 1; 
+        save = dec;
+    }
+
+    /* check overflow */
+    if (overflow == 0) 
+    {
+        *val = dec; /* return decimal value */
+    }
+    else 
+    {
+        for (i = 0; i < max; i++) 
+        {
+            /* cancel the string */
+            giet_tty_putc(0x08);
+            giet_tty_putc(0x20);
+            giet_tty_putc(0x08);
+        }
+        giet_tty_putc(0x30);
+        *val = 0;         /* return 0 value */
+    }
+    return 0;
+}
+////////////////////////////////////////////////////////////////////////////////////
+// giet_tty_printf()
+////////////////////////////////////////////////////////////////////////////////////
+// This function is a simplified version of the mutek_printf() function.
+// The terminal index must be defined in the calling task context.
+// It doesn't use the IRQ_PUT interrupt, and the associated kernel buffer.
+// Only a limited number of formats are supported:
+//   - %d : signed decimal
+//   - %u : unsigned decimal
+//   - %x : hexadecimal
+//   - %c : char
+//   - %s : string
+// - Returns 0 if success, > 0 if error.
+////////////////////////////////////////////////////////////////////////////////////
+int giet_tty_printf(char * format, ...) 
+{
+    va_list ap;
+    va_start(ap, format);
+    unsigned int ret;
+
+    if (GIET_MONO_TTY)
+    {
+        ret = sys_call(SYSCALL_TTY_LOCK, 0, 0, 0, 0); // Get TTY lock
+    }
+
+printf_text:
+
+    while (*format) 
+    {
+        unsigned int i;
+        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
+        if (i) 
+        {
+            ret = sys_call(SYSCALL_TTY_WRITE, 
+                           (unsigned int)format,
+                           i, 
+                           0xFFFFFFFF,
+                           0);
+
+            if (ret != i) goto return_error;
+
+            format += i;
+        }
+        if (*format == '%') 
+        {
+            format++;
+            goto printf_arguments;
+        }
+    }
+
+    if (GIET_MONO_TTY)
+    {
+        ret = sys_call(SYSCALL_TTY_LOCK, 1, 0, 0, 0); // Release TTY lock
+    }
+
+    va_end(ap);
+    return 0;
+
+printf_arguments:
+
+    {
+        int val = va_arg(ap, long);
+        char buf[20];
+        char * pbuf;
+        unsigned int len = 0;
+        static const char HexaTab[] = "0123456789ABCDEF";
+        unsigned int i;
+
+        switch (*format++) {
+            case ('c'):             /* char conversion */
+                len = 1;
+                buf[0] = val;
+                pbuf = buf;
+                break;
+            case ('d'):             /* decimal signed integer */
+                if (val < 0) 
+                {
+                    val = -val;
+                    ret = sys_call(SYSCALL_TTY_WRITE, 
+                                   (unsigned int)"-",
+                                   1,
+                                   0xFFFFFFFF,
+                                   0);
+                    if (ret != 1) goto return_error;
+                }
+            case ('u'):             /* decimal unsigned integer */
+                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'):             /* hexadecimal integer */
+                ret = sys_call(SYSCALL_TTY_WRITE,
+                               (unsigned int)"0x",
+                               2,
+                               0xFFFFFFFF,
+                               0);
+                if (ret != 2) goto return_error;       /* return error */
+                for(i = 0; i < 8; i++) 
+                {
+                    buf[7 - i] = HexaTab[val % 16U];
+                    if (!(val /= 16U))  break;
+                }
+                len =  i + 1;
+                pbuf = &buf[7 - i];
+                break;
+            case ('s'):             /* string */
+                {
+                    char * str = (char *) val;
+                    while (str[len]) 
+                    {
+                        len++;
+                    }
+                    pbuf = (char *) val;
+                }
+                break;
+            default:
+                goto printf_text;
+        }
+
+        ret = sys_call(SYSCALL_TTY_WRITE, 
+                       (unsigned int)pbuf,
+                       len,
+                       0xFFFFFFFF,
+                       0);
+        if (ret != len)  goto return_error;
+        
+        goto printf_text;
+    }
+
+return_error:
+    if (GIET_MONO_TTY)
+    {
+        ret = sys_call(SYSCALL_TTY_LOCK, 1, 0, 0, 0); // Release TTY lock
+    }
+
+    return 1;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////////
+/////////////////////  TIMER related system calls //////////////////////////////// 
+//////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////
+// giet_timer_start()
+//////////////////////////////////////////////////////////////////////////////////
+// This function activates the private user timer allocated to the calling task
+// in the boot phase.
+// - Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_timer_start() 
+{
+    return sys_call( SYSCALL_TIMER_START, 
+                     0, 0, 0, 0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_timer_stop()
+//////////////////////////////////////////////////////////////////////////////////
+// This function activates the user timer allocated to the calling task.
+// - Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_timer_stop() 
+{
+    return sys_call( SYSCALL_TIMER_STOP, 
+                     0, 0, 0, 0 );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
+///////////////  Frame buffer device related system calls  ///////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////
+// giet_fb_sync_write()
+//////////////////////////////////////////////////////////////////////////////////
+// This blocking function use a memory copy strategy to transfer data from a
+// user buffer to the frame buffer device in kernel space.
+//     offset : offset (in bytes) in the frame buffer
+//     buffer : base address of the memory buffer
+//     length : number of bytes to be transfered
+// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
+//////////////////////////////////////////////////////////////////////////////////
+int giet_fb_sync_write( unsigned int offset, 
+                        void *       buffer, 
+                        unsigned int length ) 
+{
+    return sys_call( SYSCALL_FB_SYNC_WRITE, 
+                     offset, 
+                     (unsigned int)buffer, 
+                     length, 
+                     0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_fb_sync_read()
+//////////////////////////////////////////////////////////////////////////////////
+// This blocking function use a memory copy strategy to transfer data from the
+// frame buffer device in kernel space to an user buffer.
+//     offset : offset (in bytes) in the frame buffer
+//     buffer : base address of the user buffer
+//     length : number of bytes to be transfered
+// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
+//////////////////////////////////////////////////////////////////////////////////
+int giet_fb_sync_read( unsigned int offset, 
+                       void *       buffer, 
+                       unsigned int length ) 
+{
+    return sys_call( SYSCALL_FB_SYNC_READ, 
+                     offset, 
+                     (unsigned int)buffer, 
+                     length, 
+                     0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_fb_cma_init()
+//////////////////////////////////////////////////////////////////////////////////
+// This function initializes the two chbuf SRC an DST used by the CMA controller 
+// and activates the CMA channel allocated to the calling task.
+// - buf0   : first user buffer virtual address
+// - buf0   : second user buffer virtual address
+// - length : buffer size (bytes)
+// - Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_fb_cma_init( void *       buf0,
+                      void *       buf1,
+                      unsigned int length )
+{
+    return sys_call( SYSCALL_FB_CMA_INIT, 
+                     (unsigned int)buf0, 
+                     (unsigned int)buf1, 
+                     length, 
+                     0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_fb_cma_write()
+//////////////////////////////////////////////////////////////////////////////////
+// This function set the valid status for one of the SRC user buffer.
+// and reset the valid status for the DST frame buffer.
+// - bufffer_id : 0 => buf0 valid is set / not 0  => buf1 valid is set
+// - Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_fb_cma_write( unsigned int buffer_id )
+{
+    return sys_call( SYSCALL_FB_CMA_WRITE, 
+                     buffer_id, 
+                     0, 0, 0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_fb_cma_stop()
+//////////////////////////////////////////////////////////////////////////////////
+// This function desactivates the CMA channel allocated to the calling task.
+// - Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_fb_cma_stop( )
+{
+    return sys_call( SYSCALL_FB_CMA_STOP, 
+                     0, 0, 0, 0 );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
+/////////////////////// NIC related system calls /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////////
+// giet_nic_cma_init()
+//////////////////////////////////////////////////////////////////////////////////
+// This function initializes the memory chbuf used by the CMA controller, 
+// activates the NIC channel allocated to the calling task, and the CMA channel.
+// - tx     : RX channel if 0 / TX channel if non 0
+// - buf0   : first user buffer virtual address
+// - buf1   : second user buffer virtual address
+// - length : buffer size (bytes)
+// - Returns 0 if success, > 0 if error 
+//////////////////////////////////////////////////////////////////////////////////
+int giet_nic_cma_start()
+{
+    return sys_call( SYSCALL_NIC_CMA_START,
+                     0, 0, 0, 0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_nic_cma_stop()
+//////////////////////////////////////////////////////////////////////////////////
+// This function desactivates the NIC channel and the two CMA channels
+// allocated to the calling task.
+// - Returns 0 if success, > 0 if error.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_nic_cma_stop( )
+{
+    return sys_call( SYSCALL_NIC_CMA_STOP,
+                     0, 0, 0, 0 );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
+///////////////////// Miscellaneous system calls /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// giet_assert()
+///////////////////////////////////////////////////////////////////////////////////
+// This function uses the giet_tty_puts() and giet_exit() system calls.
+///////////////////////////////////////////////////////////////////////////////////
+void giet_assert( unsigned int condition,
+                  char*        string )
+{
+    if ( condition == 0 )
+    {
+        giet_tty_puts( string );
+        giet_exit();
+    }
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_vobj_get_vbase()
+//////////////////////////////////////////////////////////////////////////////////
+// This function writes in argument (vobj_vaddr) the virtual base address 
+// of a vobj (defined in the mapping_info data structure), identified by 
+// the two arguments (vspace_name and vobj_name).
+// The (vobj_type) argument is redundant, and used for coherence checking.
+// - Returns the address if success,  0 if error ( not defined or wrong type )
+//////////////////////////////////////////////////////////////////////////////////
+int giet_vobj_get_vbase( char*         vspace_name, 
+                         char*         vobj_name, 
+                         unsigned int  vobj_type, 
+                         unsigned int* vobj_vaddr ) 
+{
+    return sys_call( SYSCALL_VOBJ_GET_VBASE, 
+                     (unsigned int) vspace_name,
+                     (unsigned int) vobj_name,
+                     (unsigned int) vobj_type,
+                     (unsigned int) vobj_vaddr );
+}
+////////////////////////////////////////////////////////////////////////////////////
+// giet_proc_number()
+////////////////////////////////////////////////////////////////////////////////////
+// This function returns in the buffer argument the number of processors 
+// in the cluster specified by the cluster_id argument.
+// - Returns 0 if success, > 0 if error ( cluster index too large )
+////////////////////////////////////////////////////////////////////////////////////
+int giet_proc_number( unsigned int  cluster_id, 
+                      unsigned int* buffer ) 
+{
+    return sys_call(SYSCALL_PROC_NUMBER, cluster_id, (unsigned int) buffer, 0, 0);
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_exit()
+//////////////////////////////////////////////////////////////////////////////////
+// This function stops execution of the calling task with a TTY message, 
+// the user task is descheduled and becomes not runable. 
+// It does not consume processor cycles anymore.
+//////////////////////////////////////////////////////////////////////////////////
+void giet_exit() 
+{
+    sys_call( SYSCALL_EXIT,
+              0, 0, 0, 0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_context_switch()
+//////////////////////////////////////////////////////////////////////////////////
+// The user task calling this function is descheduled and
+// the processor is allocated to another task.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_context_switch() 
+{
+    return sys_call( SYSCALL_CTX_SWITCH,
+                     0, 0, 0, 0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_proc_task_id()
+//////////////////////////////////////////////////////////////////////////////////
+// This functions returns the local task id.
+// If processor has n tasks the local task index is ranging from 0 to n-1
+//////////////////////////////////////////////////////////////////////////////////
+int giet_proc_task_id() 
+{
+    return sys_call( SYSCALL_LOCAL_TASK_ID, 
+                     0, 0, 0, 0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_heap_info()
+//////////////////////////////////////////////////////////////////////////////////
+// This function returns the base address and size of the current task's heap
+//////////////////////////////////////////////////////////////////////////////////
+int giet_heap_info( unsigned int* vaddr, 
+                             unsigned int* length ) 
+{
+    return sys_call( SYSCALL_HEAP_INFO, 
+                     (unsigned int)vaddr, 
+                     (unsigned int)length, 
+                     0, 0 );
+}
+//////////////////////////////////////////////////////////////////////////////////
+// giet_global_task_id()
+//////////////////////////////////////////////////////////////////////////////////
+// This functions returns the global task id, which is unique in all the giet.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_global_task_id() 
+{
+    return sys_call( SYSCALL_GLOBAL_TASK_ID, 
+                     0, 0, 0, 0 );
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+// giet_thread_id()
+//////////////////////////////////////////////////////////////////////////////////
+// This functions returns the thread index of the current task.
+//////////////////////////////////////////////////////////////////////////////////
+int giet_thread_id() 
+{
+    return sys_call( SYSCALL_THREAD_ID, 
+                     0, 0, 0, 0 );
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+///////////////////// FAT related system calls ////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// giet_fat_open()
+///////////////////////////////////////////////////////////////////////////////////
+// Open a file identified by a pathname, and contained in the system FAT.
+// The read/write flags are not supported yet: no effect.
+///////////////////////////////////////////////////////////////////////////////////
+int giet_fat_open( const char*   pathname, 
+                   unsigned int  flags )
+{
+    return sys_call( SYSCALL_FAT_OPEN, 
+                     (unsigned int)pathname, 
+                     flags,
+                     0, 0 );
+}
+///////////////////////////////////////////////////////////////////////////////////
+// giet_fat_read()
+///////////////////////////////////////////////////////////////////////////////////
+// Read "count" sectors from a file identified by "fd", skipping "offset"
+// sectors in file, and writing into the user "buffer". 
+// The user buffer base address shoulb be 64 bytes aligned.
+///////////////////////////////////////////////////////////////////////////////////
+// This system call specification should evolve to the UNIX specification:
+// - count must be a number of bytes, with no alignment constraint on user buffer.
+// - offset argument should be removed and replaced by an implicit "lseek" pointer
+//   stored in the file descriptor.
+// This suppose to implement a sectors cache
+///////////////////////////////////////////////////////////////////////////////////
+int giet_fat_read( unsigned int fd, 
+                   void*        buffer, 
+                   unsigned int count,
+                   unsigned int offset )
+{
+    return sys_call( SYSCALL_FAT_READ,
+                     fd, 
+                     (unsigned int)buffer,
+                     count, 
+                     offset );
+}
+///////////////////////////////////////////////////////////////////////////////////
+// giet_fat_write()
+///////////////////////////////////////////////////////////////////////////////////
+// Write "count" sectors from a file identified by "fd", skipping "offset"
+// sectors in file, and reading from the user "buffer". 
+// The user buffer base address shoulb be 64 bytes aligned.
+///////////////////////////////////////////////////////////////////////////////////
+// This system call specification should evolve to the UNIX specification:
+// - count must be a number of bytes, with no alignment constraint on buffer
+// - offset argument should be removed and replaced by an implicit "lseek" pointer
+//   stored in the file descriptor.
+// This suppose to implement a sectors cache
+///////////////////////////////////////////////////////////////////////////////////
+int giet_fat_write( unsigned int fd,
+                    void*        buffer, 
+                    unsigned int count,
+                    unsigned int offset )
+{
+    return sys_call( SYSCALL_FAT_WRITE, 
+                     fd, 
+                     (unsigned int)buffer,
+                     count, 
+                     offset );
+}
+///////////////////////////////////////////////////////////////////////////////////
+// giet_fat_lseek()
+///////////////////////////////////////////////////////////////////////////////////
+// Change the lseek file pointer value for a file identified by "fd".
+///////////////////////////////////////////////////////////////////////////////////
+int giet_fat_lseek( unsigned int fd, 
+                    unsigned int offset, 
+                    unsigned int whence)
+{
+    return sys_call( SYSCALL_FAT_LSEEK, 
+                     fd, 
+                     offset, 
+                     whence, 
+                     0 );
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// giet_fat_fstat()
+///////////////////////////////////////////////////////////////////////////////////
+// Return stats of a file identified by "fd". 
+// (Only the file_size in sectors for this moment)
+///////////////////////////////////////////////////////////////////////////////////
+int giet_fat_fstat( unsigned int fd )
+{
+    return sys_call( SYSCALL_FAT_FSTAT,
+                     fd,
+                     0, 0, 0 );
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// giet_fat_close()
+///////////////////////////////////////////////////////////////////////////////////
+// Close a file identified by "fd".
+///////////////////////////////////////////////////////////////////////////////////
+int giet_fat_close( unsigned int fd )
+{
+    return sys_call( SYSCALL_FAT_CLOSE,
+                     fd,
+                     0, 0, 0 );
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+////////////////// Pseudo system calls (no syscall instruction) ///////////////////
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// giet_rand()
+// This function returns a pseudo-random value derived from the processor cycle
+// count. This value is comprised between 0 & 65535.
+///////////////////////////////////////////////////////////////////////////////////
+int giet_rand() 
+{
+    unsigned int x = sys_call(SYSCALL_PROCTIME, 0, 0, 0, 0);
+    if ((x & 0xF) > 7) {
+        return (x*x & 0xFFFF);
+    }
+    else {
+        return (x*x*x & 0xFFFF);
+    }
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/stdio.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/stdio.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/stdio.h	(revision 283)
@@ -0,0 +1,227 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : stdio.h         
+// Date     : 01/04/2010
+// Author   : alain greiner & Joel Porquet
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _STDIO_H
+#define _STDIO_H
+
+// These define must be synchronised with 
+// the _syscall_vector defined in file sys_handler.c
+
+#define SYSCALL_PROCID            0x00
+#define SYSCALL_PROCTIME          0x01
+#define SYSCALL_TTY_WRITE         0x02
+#define SYSCALL_TTY_READ          0x03
+#define SYSCALL_TIMER_START       0x04
+#define SYSCALL_TIMER_STOP        0x05
+#define SYSCALL_FREE_06           0x06
+#define SYSCALL_FREE_07           0x07
+#define SYSCALL_HEAP_INFO         0x08
+#define SYSCALL_LOCAL_TASK_ID     0x09
+#define SYSCALL_GLOBAL_TASK_ID    0x0A
+#define SYSCALL_FB_CMA_INIT       0x0B
+#define SYSCALL_FB_CMA_WRITE      0x0C
+#define SYSCALL_FB_CMA_STOP       0x0D
+#define SYSCALL_EXIT              0x0E
+#define SYSCALL_PROC_NUMBER       0x0F
+
+#define SYSCALL_FB_SYNC_WRITE     0x10
+#define SYSCALL_FB_SYNC_READ      0x11
+#define SYSCALL_THREAD_ID         0x12
+#define SYSCALL_TTY_LOCK          0x13
+#define SYSCALL_FREE_14           0x14
+#define SYSCALL_FREE_15           0x15
+#define SYSCALL_FREE_16           0x16
+#define SYSCALL_FREE_17           0x17
+#define SYSCALL_FREE_18           0x18
+#define SYSCALL_CTX_SWITCH        0x19
+#define SYSCALL_VOBJ_GET_VBASE    0x1A
+#define SYSCALL_FREE_1B           0x1B
+#define SYSCALL_NIC_CMA_START     0x1C
+#define SYSCALL_NIC_CMA_STOP      0x1D
+#define SYSCALL_NIC_SYNC_READ     0x1E
+#define SYSCALL_NIC_SYNC_WRITE    0x1F
+
+#define SYSCALL_FAT_OPEN          0x20
+#define SYSCALL_FAT_READ          0x21
+#define SYSCALL_FAT_WRITE         0x22
+#define SYSCALL_FAT_LSEEK         0x23
+#define SYSCALL_FAT_FSTAT         0x24
+#define SYSCALL_FAT_CLOSE         0x25
+
+//////////////////////////////////////////////////////////////////////////////////
+// This generic C function is used to implement all system calls.
+// It writes the system call arguments in the proper registers,
+// and tells GCC what has been modified by system call execution.
+//////////////////////////////////////////////////////////////////////////////////
+static inline int sys_call( int call_no,
+                            int arg_0, 
+                            int arg_1, 
+                            int arg_2, 
+                            int arg_3 ) 
+{
+    register int reg_no_and_output asm("v0") = call_no;
+    register int reg_a0 asm("a0") = arg_0;
+    register int reg_a1 asm("a1") = arg_1;
+    register int reg_a2 asm("a2") = arg_2;
+    register int reg_a3 asm("a3") = arg_3;
+
+    asm volatile(
+            "syscall"
+            : "=r" (reg_no_and_output)  /* output argument */
+            : "r" (reg_a0),             /* input arguments */
+            "r" (reg_a1),
+            "r" (reg_a2),
+            "r" (reg_a3),
+            "r" (reg_no_and_output)
+            : "memory",
+            /* These persistant registers will be saved on the stack by the
+             * compiler only if they contain relevant data. */
+            "at",
+            "v1",
+            "ra",
+            "t0",
+            "t1",
+            "t2",
+            "t3",
+            "t4",
+            "t5",
+            "t6",
+            "t7",
+            "t8",
+            "t9"
+               );
+    return reg_no_and_output;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// MIPS32 related system calls 
+//////////////////////////////////////////////////////////////////////////
+
+extern int giet_procid();
+
+extern int giet_proctime();
+
+//////////////////////////////////////////////////////////////////////////
+// TTY device related system calls 
+//////////////////////////////////////////////////////////////////////////
+
+extern int giet_tty_putc(char byte);
+
+extern int giet_tty_puts(char* buf);
+
+extern int giet_tty_putw(unsigned int val);
+
+extern int giet_tty_getc_no_irq(char* byte);
+
+extern int giet_tty_getc(char* byte);
+
+extern int giet_tty_gets(char* buf, unsigned int bufsize);
+
+extern int giet_tty_getw(unsigned int* val);
+
+extern int giet_tty_printf(char* format,...);
+
+//////////////////////////////////////////////////////////////////////////
+// TIMER device related system calls 
+//////////////////////////////////////////////////////////////////////////
+
+extern int giet_timer_start();
+
+extern int giet_timer_stop();
+ 
+//////////////////////////////////////////////////////////////////////////
+// Frame buffer device related system calls 
+//////////////////////////////////////////////////////////////////////////
+
+extern int giet_fb_sync_read( unsigned int offset, 
+                              void*        buffer, 
+                              unsigned int length );
+
+extern int giet_fb_sync_write(unsigned int offset, 
+                              void*        buffer, 
+                              unsigned int length);
+
+extern int giet_fb_cma_init(  void*        buf0, 
+                              void*        buf1,
+                              unsigned int length);
+
+extern int giet_fb_cma_write(unsigned int buf_id);
+
+extern int giet_fb_cma_stop();
+
+//////////////////////////////////////////////////////////////////////////
+// Network controller related system calls 
+//////////////////////////////////////////////////////////////////////////
+
+extern int giet_nic_cma_start();
+
+extern int giet_nic_cma_stop();
+
+//////////////////////////////////////////////////////////////////////////
+// FAT related system calls 
+//////////////////////////////////////////////////////////////////////////
+
+extern int giet_fat_open(  const char*  pathname,
+                           unsigned int flags );
+
+extern int giet_fat_read(  unsigned int fd,
+                           void*        buffer,
+                           unsigned int count,
+                           unsigned int offset );
+
+extern int giet_fat_write( unsigned int fd,
+                           void*        buffer,
+                           unsigned int count,
+                           unsigned int offset );
+
+extern int giet_fat_lseek( unsigned int fd,
+                           unsigned int offset,
+                           unsigned int whence );
+
+extern int giet_fat_fstat( unsigned int fd );
+
+extern int giet_fat_close( unsigned int fd );
+
+//////////////////////////////////////////////////////////////////////////
+// Miscelaneous system calls
+//////////////////////////////////////////////////////////////////////////
+
+extern int giet_vobj_get_vbase( char*         vspace_name, 
+                                char*         vobj_name, 
+                                unsigned int  vobj_type, 
+                                unsigned int* vobj_vaddr);
+
+extern int giet_procnumber();
+
+extern void giet_exit();
+
+extern int giet_context_switch();
+
+extern int giet_proc_task_id();
+
+extern int giet_heap_info( unsigned int* vaddr, 
+                           unsigned int* size );
+
+extern int giet_global_task_id();
+
+extern int giet_thread_id();
+
+extern void giet_assert( unsigned int, 
+                         char* string );
+
+extern int giet_rand();
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_libs/stdlib.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/stdlib.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/stdlib.c	(revision 283)
@@ -0,0 +1,76 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : stdlib.c 
+// Date     : 05/12/2013
+// Author   : ClÃ©ment DEVIGNE
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#include <stdlib.h>
+
+///////////////////////////////////////////////////////////////////////////////////
+// int atoi ( char * str )
+///////////////////////////////////////////////////////////////////////////////////
+        
+int atoi(char *str)
+{
+    int res  = 0; // Initialize result
+    int sign = 1; // Initialize sign as positive
+    int i    = 0; // Initialize index of first digit
+
+    if (str[0] == '-') //If number is negative, then update sign
+    {
+        sign = -1;  
+        i++;           // Also update index of first digit
+    }
+
+    for (; str[i] != '\0'; ++i) // Iterate through all digits and update the result
+    {
+        res = res*10 + str[i] - '0';
+    }
+
+    // Return result with sign
+    return sign*res;
+}
+        
+////////////////////////////////////////////////////////////////////////////////////////
+//  mempcy()
+// GCC requires this function. Taken from MutekH.
+////////////////////////////////////////////////////////////////////////////////////////
+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;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+//  mempcy()
+// GCC requires this function. Taken from MutekH.
+////////////////////////////////////////////////////////////////////////////////////////
+inline void * memset(void * dst, int s, unsigned int count) {
+    char * a = (char *) dst;
+    while (count--){
+        *a++ = (char)s;
+    }
+    return dst;
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: /branch/giet_vm_ioc_drivers/giet_libs/stdlib.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/stdlib.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/stdlib.h	(revision 283)
@@ -0,0 +1,32 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : stdlib.h 
+// Date     : 05/12/2013
+// Author   : ClÃ©ment DEVIGNE
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+int atoi (char * str);
+
+////////////////////////////////////////////////////////////////////////////////////////
+//  mempcy()
+// GCC requires this function. Taken from MutekH.
+////////////////////////////////////////////////////////////////////////////////////////
+void * memcpy(void *_dst, const void * _src, unsigned int size);
+
+////////////////////////////////////////////////////////////////////////////////////////
+//  mempcy()
+// GCC requires this function. Taken from MutekH.
+////////////////////////////////////////////////////////////////////////////////////////
+inline void * memset(void * dst, int s, unsigned int count);
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: /branch/giet_vm_ioc_drivers/giet_libs/string.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/string.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/string.c	(revision 283)
@@ -0,0 +1,45 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : string.c 
+// Date     : 23/05/2013
+// Author   : Alexandre JOANNOU, Laurent LAMBERT
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// char * strcpy ( char * destination, const char * source )
+///////////////////////////////////////////////////////////////////////////////////
+char * strcpy ( char * destination, const char * source )
+{
+    if (!destination || !source)
+        return destination;
+
+    while (*source)
+        *(destination++) = *(source++);
+
+    return destination;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+// int strcmp ( const char * str1, const char * str2 )
+///////////////////////////////////////////////////////////////////////////////////
+int strcmp ( const char * str1, const char * str2 )
+{
+    if (!str1 || !str2)
+        return -123456; // return a value out of the char's bounds
+
+    while (*str1 && *str1 == *str2)
+    {
+        str1++;
+        str2++;
+    }
+
+    return (*str1 - *str2);
+}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: /branch/giet_vm_ioc_drivers/giet_libs/string.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_libs/string.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_libs/string.h	(revision 283)
@@ -0,0 +1,22 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : string.h 
+// Date     : 23/05/2013
+// Author   : Alexandre JOANNOU, Laurent LAMBERT
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _STRING_H
+#define _STRING_H
+
+char * strcpy ( char * destination, const char * source );
+int strcmp ( const char * str1, const char * str2 );
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: /branch/giet_vm_ioc_drivers/giet_xml/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_xml/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_xml/Makefile	(revision 283)
@@ -0,0 +1,20 @@
+
+all: xml2bin bin2xml
+
+bin2xml: xml_driver.c mapping_info.h
+	gcc -Wall -I. -I../sys xml_driver.c -o bin2xml
+
+xml2bin: xml_parser.c mapping_info.h
+	gcc -Wall -I. -I../giet_kernel -I/usr/include/libxml2 xml_parser.c -o xml2bin -lxml2
+
+test:
+	./xml2bin map.xml test.bin
+	./bin2xml test.bin test.xml
+
+up_test:
+	./xml2bin ../map.xml ../test.bin
+	./bin2xml ../test.bin ../test.xml
+
+
+clean:
+	rm -f xml2bin bin2xml
Index: /branch/giet_vm_ioc_drivers/giet_xml/mapping_info.h
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_xml/mapping_info.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_xml/mapping_info.h	(revision 283)
@@ -0,0 +1,345 @@
+////////////////////////////////////////////////////////////////////////////
+// File     : mapping_info.h
+// Date     : 01/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+////////////////////////////////////////////////////////////////////////////
+// The MAPPING_INFO data structure, used by the GIET_VM kernel contains:
+// 
+// 1) a description of a clusterized hardware architecture.
+// The number of cluster is variable (can be one). The number of processors
+// per cluster is variable (can be one). The number of peripherals per cluser
+// and coprocessor per cluster is variable. The number of physical memory
+// banks per cluster is variable.
+//
+// 2/ a description of the applications (called vspaces) to be - statically - 
+// launched on the platform. The number of parallel tasks per application is
+// variable (can be one). Multi-Writer/Multi-Reader communication channels
+// betwwen tasks are supported. Each vspace contains a variable number 
+// of virtual segments (called vsegs).
+//
+// 3/ the mapping directives: both tasks on processors, and software objects 
+// (vobjs and vsegs) on the physical memory banks (called psegs).
+// and a variable number of tasks. The number of virtual space can be one.
+//
+// The mapping_info data structure is organised as the concatenation of
+// a fixed size header, and 11 variable size arrays:
+//
+// - mapping_cluster_t  cluster[]  
+// - mapping_pseg_t     pseg[]       
+// - mapping_vspace_t   vspace[]  
+// - mapping_vseg_t     vseg[]     
+// - mapping_vseg_t     vobj[]    
+// - mapping_task_t     task[]  
+// - mapping_proc_t     proc[]  
+// - mapping_irq_t      irq[]   
+// - mapping_coproc_t   coproc[]
+// - mapping_cp_port_t  cp_port[] 
+// - mapping_periph_t   periph[]
+//
+// It is intended to be stored in memory in the seg_boot_mapping segment. 
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MAPPING_INFO_H_
+#define _MAPPING_INFO_H_
+
+#define MAPPING_HEADER_SIZE   sizeof(mapping_header_t)
+#define MAPPING_CLUSTER_SIZE  sizeof(mapping_cluster_t)
+#define MAPPING_VSPACE_SIZE   sizeof(mapping_vspace_t)
+#define MAPPING_VSEG_SIZE     sizeof(mapping_vseg_t)
+#define MAPPING_VOBJ_SIZE     sizeof(mapping_vobj_t)
+#define MAPPING_PSEG_SIZE     sizeof(mapping_pseg_t)
+#define MAPPING_TASK_SIZE     sizeof(mapping_task_t)
+#define MAPPING_PROC_SIZE     sizeof(mapping_proc_t)
+#define MAPPING_IRQ_SIZE      sizeof(mapping_irq_t)
+#define MAPPING_COPROC_SIZE   sizeof(mapping_coproc_t)
+#define MAPPING_CP_PORT_SIZE  sizeof(mapping_cp_port_t)
+
+#define C_MODE_MASK  0b1000   // cacheable
+#define X_MODE_MASK  0b0100   // executable
+#define W_MODE_MASK  0b0010   // writable
+#define U_MODE_MASK  0b0001   // user access
+
+#define IN_MAPPING_SIGNATURE    0xDEADBEEF
+#define OUT_MAPPING_SIGNATURE   0xBABEF00D
+
+typedef unsigned long long  paddr_t;
+
+enum vobjType 
+{
+    VOBJ_TYPE_ELF      = 0,  // loadable code/data object of elf files
+    VOBJ_TYPE_BLOB     = 1,  // loadable blob object
+    VOBJ_TYPE_PTAB     = 2,  // page table 
+    VOBJ_TYPE_PERI     = 3,  // hardware component
+    VOBJ_TYPE_MWMR     = 4,  // MWMR channel
+    VOBJ_TYPE_LOCK     = 5,  // Lock
+    VOBJ_TYPE_BUFFER   = 6,  // Any "no initialization" objects (stacks...)
+    VOBJ_TYPE_BARRIER  = 7,  // Barrier
+    VOBJ_TYPE_CONST    = 8,  // Constant
+    VOBJ_TYPE_MEMSPACE = 9,  // Memspace (descriptor must be initialised)
+    VOBJ_TYPE_SCHED    = 10, // Array of schedulers (one per cluster)
+    VOBJ_TYPE_BOOT     = 11, // loader by the preloader
+};
+
+enum irqType
+{
+    IRQ_TYPE_HWI = 0,        // HARD in map.xml file
+    IRQ_TYPE_SWI = 1,        // SOFT in map.xml file,
+    IRQ_TYPE_PTI = 2,        // TIME in map.xml file,
+};
+
+enum psegType 
+{
+    PSEG_TYPE_RAM  = 0,
+    PSEG_TYPE_ROM  = 1,      // deprecated => you should use PSEG_TYPE_PERI  
+    PSEG_TYPE_PERI = 2,
+};
+
+// The enum definitions for psegType and periphType must be kept
+// consistent with the definitions in the xml_driver.c file...
+
+enum periphType 
+{
+    PERIPH_TYPE_CMA       = 0,
+    PERIPH_TYPE_DMA       = 1,
+    PERIPH_TYPE_FBF       = 2,
+    PERIPH_TYPE_HBA       = 3,
+    PERIPH_TYPE_ICU       = 4,
+    PERIPH_TYPE_IOB       = 5,
+    PERIPH_TYPE_IOC       = 6,
+    PERIPH_TYPE_MMC       = 7,
+    PERIPH_TYPE_MWR       = 8,
+    PERIPH_TYPE_NIC       = 9,
+    PERIPH_TYPE_ROM       = 10,
+    PERIPH_TYPE_SIM       = 11,
+    PERIPH_TYPE_TIM       = 12,
+    PERIPH_TYPE_TTY       = 13,
+    PERIPH_TYPE_XCU       = 14,
+
+    PERIPH_TYPE_MAX_VALUE = 15,
+};
+
+enum periphSubtype 
+{
+    PERIPH_SUBTYPE_BDV       = 0,
+    PERIPH_SUBTYPE_HBA       = 1,
+    PERIPH_SUBTYPE_SPI       = 2,
+
+    PERIPH_SUBTYPE_MAX_VALUE = 3,
+};
+
+enum mwmrPortDirection 
+{
+    PORT_TO_COPROC   = 0, // status register
+    PORT_FROM_COPROC = 1, // config register
+};
+
+
+////////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_header_s 
+{
+    unsigned int signature;          // must contain MAPPING_SIGNATURE
+    unsigned int x_size;             // actual number of clusters in a row
+    unsigned int y_size;             // actual number of clusters in a column
+    unsigned int x_width;            // number of bits to encode x coordinate 
+    unsigned int y_width;            // number of bits to encode y coordinate 
+    unsigned int globals;            // number of vsegs mapped in all vspaces
+    unsigned int vspaces;            // number of virtual spaces
+    unsigned int increment;          // vseg cluster increment for replicated periphs
+
+    unsigned int cma_cluster;        // index of cluster containing CMA controler
+    unsigned int cma_cluster_bis;    // index of cluster containing second CMA controler
+
+    unsigned int fbf_cluster;        // index of cluster containing FBF controler
+    unsigned int fbf_cluster_bis;    // index of cluster containing second FBF controler
+
+    unsigned int hba_cluster;        // index of cluster containing HBA controler
+    unsigned int hba_cluster_bis;    // index of cluster containing second HBA controler
+
+    unsigned int iob_cluster;        // index of cluster containing IOB controler
+    unsigned int iob_cluster_bis;    // index of cluster containing second IOB controler
+
+    unsigned int ioc_cluster;        // index of cluster containing IOC controler
+    unsigned int ioc_cluster_bis;    // index of cluster containing second IOC controler
+
+    unsigned int nic_cluster;        // index of cluster containing NIC controler
+    unsigned int nic_cluster_bis;    // index of cluster containing second NIC controler
+
+    unsigned int rom_cluster;        // index of cluster containing ROM controler
+    unsigned int rom_cluster_bis;    // index of cluster containing second ROM controler
+
+    unsigned int sim_cluster;        // index of cluster containing SIM controler
+    unsigned int sim_cluster_bis;    // index of cluster containing second SIM controler
+
+    unsigned int tty_cluster;        // index of cluster containing TTY controler
+    unsigned int tty_cluster_bis;    // index of cluster containing second TTY controler
+
+    unsigned int psegs;              // total number of physical segments (for all clusters)
+    unsigned int vsegs;              // total number of virtual segments (for all vspaces)
+    unsigned int vobjs;              // total number of virtual objects (for all vspaces)
+    unsigned int tasks;              // total number of tasks (for all vspaces)
+    unsigned int procs;              // total number of procs (for all clusters)
+    unsigned int irqs;               // total number of irqs (for all processors)
+    unsigned int coprocs;            // total number of coprocs (for all clusters)
+    unsigned int cp_ports;           // total number of cp_ports (for all coprocs)
+    unsigned int periphs;            // total number of peripherals (for all clusters)
+
+    char name[32];                   // mapping name
+} mapping_header_t;
+
+
+/////////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_cluster_s 
+{
+    unsigned int    x;               // x coordinate
+    unsigned int    y;               // y coordinate
+
+    unsigned int    psegs;           // number of psegs in cluster
+    unsigned int    pseg_offset;     // index of first pseg in pseg set
+
+    unsigned int    procs;           // number of processors in cluster
+    unsigned int    proc_offset;     // index of first proc in proc set
+ 
+    unsigned int    coprocs;         // number of coprocessors in cluster
+    unsigned int    coproc_offset;   // index of first coproc in coproc set
+
+    unsigned int    periphs;         // number of peripherals in cluster
+    unsigned int    periph_offset;   // index of first coproc in coproc set
+} mapping_cluster_t;
+
+
+////////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_vspace_s 
+{
+    char            name[32];        // virtual space name
+    unsigned int    start_offset;    // offset of the vobj containing start vector
+    unsigned int    vsegs;           // number of vsegs in vspace
+    unsigned int    vobjs;           // number of vobjs in vspace
+    unsigned int    tasks;           // number of tasks in vspace
+    unsigned int    vseg_offset;     // index of first vseg in vspace 
+    unsigned int    vobj_offset;     // index of first vobjs in vspace
+    unsigned int    task_offset;     // index of first task in vspace
+} mapping_vspace_t;
+
+
+//////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_vseg_s 
+{
+    char            name[32];        // vseg name (unique in vspace)
+    unsigned int    vbase;           // base address in virtual space
+    paddr_t         pbase;           // base address in physical space
+    unsigned int    length;          // size (bytes)
+    unsigned int    psegid;          // physical segment global index
+    unsigned int    mode;            // C-X-W-U flags
+    unsigned int    vobjs;           // number of vobjs in vseg
+    unsigned int    vobj_offset;     // index of first vobj in vseg
+    unsigned int    next_vseg;       // linked list of vsegs mapped on pseg
+    char            mapped;          // mapped if non zero
+    char            ident;           // identity mapping if non zero
+    char            rsvd0;           // reserved 
+    char            rsvd1;           // reserved
+} mapping_vseg_t;
+
+
+//////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_pseg_s  
+{
+    char            name[32];        // pseg name (unique in a cluster)
+    paddr_t         base;            // base address in physical space
+    paddr_t         length;          // size (bytes)
+    unsigned int    type;            // RAM / PERI
+    unsigned int    clusterid;       // linear index in array of clusters
+    unsigned int    next_vseg;       // linked list of vsegs mapped on pseg
+} mapping_pseg_t;
+
+
+//////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_task_s 
+{
+    char            name[32];        // task name (unique in vspace)
+    unsigned int    clusterid;       // linear index in array of clusters
+    unsigned int    proclocid;       // processor local index (inside cluster)
+    unsigned int    trdid;           // thread index in vspace
+    unsigned int    stack_vobjid;    // stack vobj index in vspace
+    unsigned int    heap_vobjid;     // heap vobj index in vspace
+    unsigned int    startid;         // index in start_vector 
+    unsigned int    use_tty;         // TTY channel required (global)
+    unsigned int    use_nic;         // NIC channel required (global)
+    unsigned int    use_cma;         // CMA channel required (global)
+    unsigned int    use_hba;         // IOC channel required (global)
+    unsigned int    use_tim;         // user timer required (local)
+} mapping_task_t;
+
+
+//////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_vobj_s 
+{
+    char            name[32];        // vobj name (unique in a vspace)
+    char            binpath[64];     // path for the binary code ("*.elf")
+    unsigned int    type;            // type of vobj
+    unsigned int    length;          // size (bytes)
+    unsigned int    align;           // required alignement (logarithm of 2)
+    unsigned int    vaddr;           // virtual base addresse of the vobj
+    paddr_t         paddr;           // physical base addresse of the vobj
+    unsigned int    init;            // init value (used by barrier or mwmr channel)
+} mapping_vobj_t;
+
+
+//////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_proc_s 
+{
+    unsigned int    irqs;            // number of IRQs allocated to processor
+    unsigned int    irq_offset;      // index of first IRQ allocated to processor
+} mapping_proc_t;
+
+
+/////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_irq_s 
+{
+    unsigned int    type;            // HWI / SWI / PTI
+    unsigned int    icuid;           // IRQ Index for the ICU component
+    unsigned int    isr;             // ISR Index (defined in irq_handler.h)
+    unsigned int    channel;         // Channel Index (for multi-channels peripherals)
+} mapping_irq_t; 
+
+
+////////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_coproc_s 
+{
+    char            name[32];        // coprocessor name
+    unsigned int    psegid;          // global pseg index 
+    unsigned int    ports;           // number of MWMR ports used by coprocessor
+    unsigned int    port_offset;     // index of first MWMR port used by coprocessor
+} mapping_coproc_t;
+
+
+/////////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_cp_port_s 
+{
+    unsigned int    direction;       // TO_COPROC == 0 / FROM_COPROC == 1
+    unsigned int    vspaceid;        // index of the vspace containing the MWMR channel
+    unsigned int    mwmr_vobjid;     // local index of the vobj containing the MWMR channel
+} mapping_cp_port_t;
+
+
+////////////////////////////////////////////////////////
+typedef struct __attribute__((packed))  mapping_periph_s 
+{
+    unsigned int    type;         
+    unsigned int    subtype;         // periph specialization
+    unsigned int    psegid;          // pseg index in cluster
+    unsigned int    channels;        // number of channels
+} mapping_periph_t;
+
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_xml/xml_driver.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_xml/xml_driver.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_xml/xml_driver.c	(revision 283)
@@ -0,0 +1,478 @@
+////////////////////////////////////////////////////////////////////////////
+// File     : xml_driver.c
+// Date     : 04/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+////////////////////////////////////////////////////////////////////////////
+// This program translate a binary file containing a MAPPING_INFO 
+// data structure to an xml file.
+////////////////////////////////////////////////////////////////////////////
+
+#include  <stdlib.h>
+#include  <fcntl.h>
+#include  <unistd.h>
+#include  <stdio.h>
+#include  <string.h>
+#include  <stdint.h>
+#include  <mapping_info.h>
+
+//////////////////////////////////////////////////////
+void buildXml(mapping_header_t * header, FILE * fpout) {
+    const char * vobj_type[] = 
+    { 
+        "ELF",        // binary code generated by GCC
+        "BLOB",       // binary code generated by GCC
+        "PTAB",       // page table 
+        "PERI",       // hardware component
+        "MWMR",       // MWMR channel
+        "LOCK",       // Spin-Lock
+        "BUFFER",     // Any "no intialiasation needed" objects (stacks...)
+        "BARRIER",    // Barrier
+        "CONST",      // Constant
+        "MEMSPACE",   // Memspace
+        "SCHED",      // Scheduler
+    };
+
+    const char * pseg_type[] = 
+    {
+        "RAM",
+        "ROM",
+        "PERI",
+    };
+
+    const char * irq_type[] =
+    {
+        "HARD",
+        "SOFT",
+    };
+
+    const char * isr_type[] =
+    {
+        "ISR_DEFAULT",
+        "ISR_SWITCH",
+        "ISR_TTY",
+        "ISR_DMA",
+        "ISR_IOC",
+        "ISR_TIMER",
+    };
+
+    const char * periph_type[] =
+    {
+        "CMA",
+        "DMA",
+        "FBF",
+        "HBA",
+        "ICU",
+        "IOB",
+        "IOC",
+        "MMC",
+        "MWR",
+        "NIC",
+        "ROM",
+        "SIM",
+        "TIM",
+        "TTY",
+        "XCU",
+    };
+
+    const char * periph_subtype[] =
+    {
+        "BDV",
+        "HBA",
+        "SPI",
+    };
+
+    const char * port_direction[] =
+    {
+        "TO_COPROC",
+        "FROM_COPROC",
+    };
+
+    const char * mode_str[] = 
+    { 
+        "____",
+        "___U", 
+        "__W_", 
+        "__WU", 
+        "_X__", 
+        "_X_U", 
+        "_XW_", 
+        "_XWU", 
+        "C___", 
+        "C__U", 
+        "C_W_", 
+        "C_WU", 
+        "CX__", 
+        "CX_U", 
+        "CXW_", 
+        "CXWU", 
+    };
+
+    unsigned int vspace_id;
+    unsigned int cluster_id;
+    unsigned int pseg_id;
+    unsigned int vseg_id;
+    unsigned int vobj_id;
+    unsigned int task_id;
+    unsigned int proc_id;
+    unsigned int irq_id;
+    unsigned int coproc_id;
+    unsigned int port_id;
+    unsigned int periph_id;
+
+    mapping_cluster_t * cluster;
+    mapping_pseg_t * pseg;
+    mapping_vspace_t * vspace;
+    mapping_vseg_t * vseg;
+    mapping_vobj_t * vobj;
+    mapping_task_t * task;
+    mapping_proc_t * proc;
+    mapping_irq_t * irq;    
+    mapping_coproc_t * coproc;
+    mapping_cp_port_t * cp_port;
+    mapping_periph_t * periph;
+
+    // computes the base adresss for clusters array, 
+    cluster = (mapping_cluster_t *)((char *) header +
+            MAPPING_HEADER_SIZE);
+
+    // computes the base adresss for psegs array, 
+    pseg = (mapping_pseg_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size);
+
+    // computes the base adresss for vspaces array, 
+    vspace = (mapping_vspace_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs);
+
+    // computes the base adresss for vsegs array, 
+    vseg = (mapping_vseg_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces);
+
+    // computes the base adresss for vobjs array, 
+    vobj = (mapping_vobj_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VSEG_SIZE * header->vsegs);
+
+    // computes the base address for tasks array 
+    task = (mapping_task_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs);
+
+    // computes the base address for procs array 
+    proc = (mapping_proc_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_TASK_SIZE * header->tasks);
+
+    // computes the base address for irqs array 
+    irq = (mapping_irq_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_TASK_SIZE * header->tasks +
+            MAPPING_PROC_SIZE * header->procs);
+
+    // computes the base address for coprocs array 
+    coproc = (mapping_coproc_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_TASK_SIZE * header->tasks +
+            MAPPING_PROC_SIZE * header->procs +
+            MAPPING_IRQ_SIZE * header->irqs);
+
+    // computes the base address for cp_ports array 
+    cp_port = (mapping_cp_port_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_TASK_SIZE * header->tasks +
+            MAPPING_PROC_SIZE * header->procs +
+            MAPPING_IRQ_SIZE * header->irqs +
+            MAPPING_COPROC_SIZE * header->coprocs);
+
+    // computes the base address for periphs array 
+    periph = (mapping_periph_t *) ((char *) header +
+            MAPPING_HEADER_SIZE +
+            MAPPING_CLUSTER_SIZE * header->x_size * header->y_size +
+            MAPPING_PSEG_SIZE * header->psegs +
+            MAPPING_VSPACE_SIZE * header->vspaces +
+            MAPPING_VOBJ_SIZE * header->vobjs +
+            MAPPING_VSEG_SIZE * header->vsegs +
+            MAPPING_TASK_SIZE * header->tasks +
+            MAPPING_PROC_SIZE * header->procs +
+            MAPPING_IRQ_SIZE * header->irqs +
+            MAPPING_COPROC_SIZE * header->coprocs +
+            MAPPING_CP_PORT_SIZE * header->cp_ports);
+
+    ///////////////////////// header /////////////////////////////////////////////
+
+    fprintf(fpout, "<?xml version = \"1.0\"?>\n\n");
+
+    fprintf(fpout, "<mapping_info signature = \"0x%x\" \n", header->signature);
+    fprintf(fpout, "              name      = \"%s\"   \n", header->name);
+    fprintf(fpout, "              x_size    = \"%d\"   \n", header->x_size);
+    fprintf(fpout, "              y_size    = \"%d\"   \n", header->y_size);
+    fprintf(fpout, "              x_width   = \"%d\"   \n", header->x_width);
+    fprintf(fpout, "              y_width   = \"%d\"   \n", header->y_width);
+    fprintf(fpout, "              vspaces   = \"%d\"   \n", header->vspaces);
+    fprintf(fpout, "              increment = \"%d\" >\n\n", header->vspaces);
+
+    ///////////////////// clusters ///////////////////////////////////////////////
+
+    fprintf( fpout, "    <clusterset>\n");
+    for (cluster_id = 0; cluster_id < (header->x_size * header->y_size); cluster_id++) 
+    {
+        fprintf(fpout, "        <cluster x = \"%d\" y = \"%d\" >\n", 
+                cluster[cluster_id].x, cluster[cluster_id].y );
+
+        ///////////////////// psegs   ////////////////////////////////////////////////
+
+        for (pseg_id = cluster[cluster_id].pseg_offset;
+             pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs;
+             pseg_id++) 
+        {
+            fprintf(fpout, "            <pseg name = \"%s\" ", pseg[pseg_id].name);
+            fprintf(fpout, "type = \"%s\" ", pseg_type[pseg[pseg_id].type]);
+            fprintf(fpout, "base = \"0x%llx\" ", pseg[pseg_id].base);
+            fprintf(fpout, "length = \"0x%llx\" />\n",   pseg[pseg_id].length);
+        }
+
+        ///////////////////// processors /////////////////////////////////////////////
+
+        unsigned int proc_index = 0;
+        for (proc_id = cluster[cluster_id].proc_offset;
+             proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs;
+             proc_id++) 
+        {
+            fprintf(fpout, "            <proc index = \"%d\" >\n", proc_index);
+            for (irq_id = proc[proc_id].irq_offset; 
+                 irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs;
+                 irq_id++) 
+            {
+                fprintf(fpout, "                <irq type = \"%s\" ", irq_type[irq[irq_id].type]);
+                fprintf(fpout, " icuid = \"0x%x\" ", irq[irq_id].icuid);
+                fprintf(fpout, " isr = \"%s\" ", isr_type[irq[irq_id].isr]);
+                fprintf(fpout, " channel = \"0x%x\" />\n", irq[irq_id].channel);
+            }
+            fprintf(fpout, "            </proc>\n" );
+        }
+
+
+        ///////////////////// coprocessors ///////////////////////////////////////////
+
+        for (coproc_id = cluster[cluster_id].coproc_offset;
+             coproc_id < cluster[cluster_id].coproc_offset + cluster[cluster_id].coprocs;
+             coproc_id++) 
+        {
+            fprintf(fpout, "            <coproc name = \"%s\" ", coproc[coproc_id].name);
+            fprintf(fpout, " psegname = \"%s\" >\n", pseg[coproc[coproc_id].psegid].name);
+            for (port_id = coproc[coproc_id].port_offset;
+                 port_id < coproc[coproc_id].port_offset + coproc[coproc_id].ports;
+                 port_id++) 
+            {
+                unsigned int vobj_id = cp_port[port_id].mwmr_vobjid + vspace[cp_port[port_id].vspaceid].vobj_offset; 
+                fprintf(fpout, "             <port direction = \"%s\" ",  port_direction[cp_port[port_id].direction]);
+                fprintf(fpout, " vspacename = \"%s\" ", vspace[cp_port[port_id].vspaceid].name);
+                fprintf(fpout, " vobjname = \"%s\" />\n",  vobj[vobj_id].name);
+            }
+            fprintf(fpout, "            </coproc>\n" );
+        }
+
+        ///////////////////// periphs  ///////////////////////////////////////////////
+
+        for (periph_id = cluster[cluster_id].periph_offset;
+             periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs;
+             periph_id++) 
+        {
+            fprintf(fpout, "            <periph type = \"%s\" ", periph_type[periph[periph_id].type]);
+
+            if (periph[periph_id].subtype < PERIPH_SUBTYPE_MAX_VALUE) 
+                fprintf(fpout, " subtype = \"%s\" ", periph_subtype[periph[periph_id].subtype]);
+
+            fprintf(fpout, " psegname = \"%s\" ", pseg[periph[periph_id].psegid].name);
+            fprintf(fpout, " channels = \"%d\" />\n",  periph[periph_id].channels);
+        }
+        fprintf(fpout, "        </cluster>\n" );
+    }
+    fprintf(fpout, "    </clusterset>\n\n" );
+
+    /////////////////// globals /////////////////////////////////////////////////
+
+    fprintf(fpout, "    <globalset>\n" );
+    for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 
+    {
+        unsigned int pseg_id = vseg[vseg_id].psegid; 
+
+        fprintf(fpout, "        <vseg name = \"%s\" ", vseg[vseg_id].name);
+        fprintf(fpout, "vbase = \"0x%x\" ", vseg[vseg_id].vbase);
+        fprintf(fpout, "mode  = \"%s\" ", mode_str[vseg[vseg_id].mode]);
+        fprintf(fpout, "clusterid = \"%d\" ", pseg[pseg_id].clusterid);
+        fprintf(fpout, "psegname = \"%s\" ", pseg[pseg_id].name);
+        fprintf(fpout, "ident = \"%d\" >\n", vseg[vseg_id].ident);
+        for (vobj_id = vseg[vseg_id].vobj_offset;
+             vobj_id < (vseg[vseg_id].vobj_offset + vseg[vseg_id].vobjs); 
+             vobj_id++) 
+        {
+            fprintf(fpout, "            <vobj name = \"%s\" ", vobj[vobj_id].name);
+            fprintf(fpout, "type = \"%s\" ", vobj_type[vobj[vobj_id].type]);
+            fprintf(fpout, "length = \"0x%x\" ", vobj[vobj_id].length);
+            fprintf(fpout, "align = \"%d\" ", vobj[vobj_id].align);
+            fprintf(fpout, "init = \"%d\" ", vobj[vobj_id].init);
+            fprintf(fpout, "binpath = \"%s\" />\n", vobj[vobj_id].binpath);
+        }
+        fprintf(fpout, "        </vseg>\n");
+    }
+    fprintf(fpout, "    </globalset>\n" );
+
+    //////////////////// vspaces ////////////////////////////////////////////////
+
+    fprintf( fpout, "\n    <vspaceset>\n\n" );
+    for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 
+    {
+        unsigned int func_id = vspace[vspace_id].vobj_offset + vspace[vspace_id].start_offset; 
+        fprintf(fpout, "        <vspace name = \"%s\" ", vspace[vspace_id].name); 
+        fprintf(fpout, " startname = \"%s\" >\n", vobj[func_id].name); 
+
+        //////////////////// vsegs //////////////////////////////////////////////
+
+        for (vseg_id = vspace[vspace_id].vseg_offset;
+             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);
+             vseg_id++) 
+        {
+            unsigned int pseg_id    = vseg[vseg_id].psegid; 
+            unsigned int cluster_id = pseg[pseg_id].clusterid;
+            unsigned int x          = cluster_id >> header->y_width;
+            unsigned int y          = cluster_id & ((1<<header->y_width)-1);
+
+            fprintf(fpout, "            <vseg name = \"%s\" ", vseg[vseg_id].name);
+            fprintf(fpout, "vbase = \"0x%x\" ", vseg[vseg_id].vbase);
+            fprintf(fpout, "mode = \"%s\" ", mode_str[vseg[vseg_id].mode]);
+            fprintf(fpout, "x = \"%d\" ", x);
+            fprintf(fpout, "y = \"%d\" ", y);
+            fprintf(fpout, "psegname = \"%s\" ", pseg[pseg_id].name);
+            fprintf(fpout, "ident = \"%d\" >\n", vseg[vseg_id].ident);
+
+            for (vobj_id = vseg[vseg_id].vobj_offset;
+                 vobj_id < (vseg[vseg_id].vobj_offset + vseg[vseg_id].vobjs);
+                 vobj_id++) 
+            {
+                fprintf(fpout, "             <vobj name = \"%s\" ", vobj[vobj_id].name);
+                fprintf(fpout, "type = \"%s\" ", vobj_type[vobj[vobj_id].type]);
+                fprintf(fpout, "length = \"0x%x\" ", vobj[vobj_id].length);
+                fprintf(fpout, "align = \"%d\" ", vobj[vobj_id].align);
+                fprintf(fpout, "init = \"%d\" ", vobj[vobj_id].init);
+                fprintf(fpout, "binpath = \"%s\" />\n", vobj[vobj_id].binpath);
+            }
+            fprintf(fpout, "            </vseg>\n\n");
+        }
+
+        //////////////////// tasks //////////////////////////////////////////////
+
+        for (task_id = vspace[vspace_id].task_offset;
+             task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);
+             task_id++) 
+        {
+            unsigned int stack_vobj_id = task[task_id].stack_vobjid + vspace[vspace_id].vobj_offset; 
+            unsigned int heap_vobj_id = task[task_id].heap_vobjid + vspace[vspace_id].vobj_offset; 
+            unsigned int cluster_id   = task[task_id].clusterid;
+            unsigned int x            = cluster_id >> header->y_width;
+            unsigned int y            = cluster_id & ((1<<header->y_width)-1);
+
+            fprintf(fpout, "            <task name = \"%s\" ", task[task_id].name);
+            fprintf(fpout, "x = \"%d\" ", x);
+            fprintf(fpout, "y = \"%d\" ", y);
+            fprintf(fpout, "proclocid = \"%d\" ", task[task_id].proclocid);
+            fprintf(fpout, "stackname = \"%s\" ", vobj[stack_vobj_id].name);
+            if (heap_vobj_id != -1) 
+            {
+                fprintf(fpout, "heapname = \"%s\" ", vobj[heap_vobj_id].name);
+            }
+            fprintf(fpout, "startid = \"%d\" ", task[task_id].startid);
+            fprintf(fpout, "usetty = \"%d\" ", task[task_id].use_tty);
+            fprintf(fpout, "usenic = \"%d\" ", task[task_id].use_nic);
+            fprintf(fpout, "usecma = \"%d\" ", task[task_id].use_cma);
+            fprintf(fpout, "usetim = \"%d\" ", task[task_id].use_tim);
+            fprintf(fpout, "usehba = \"%d\" />\n", task[task_id].use_hba);
+        }
+        fprintf(fpout, "        </vspace>\n\n");
+    }
+    fprintf(fpout, "    </vspaceset>\n");
+    fprintf(fpout, "</mapping_info>\n");
+} // end buildXml()
+
+
+/////////////////////////////////////
+int main(int argc, char * argv[]) {
+    if (argc < 2) {
+        printf("Usage: bin2xml <input_file_path> <output_file_path>\n");
+        return 1;
+    }
+
+    unsigned int bin[0x10000]; // 64 K int = 256 Kbytes 
+
+    int fdin = open(argv[1], O_RDONLY);
+    if (fdin < 0) {
+        perror("open");
+        exit(1);
+    }
+
+    FILE * fpout = fopen( argv[2], "w");
+    if (fpout == NULL) {
+        perror("open");
+        exit(1);
+    }
+
+    unsigned int length = read(fdin, bin, 0x40000);
+
+    if (length <= 0) {
+        perror("read");
+        exit(1);
+    }
+
+    if (bin[0] == IN_MAPPING_SIGNATURE) {
+        buildXml((mapping_header_t *) bin, fpout);
+    } 
+    else {
+        printf("[ERROR] Wrong file format\n");
+        exit(1);
+    }
+    return 0;
+} // end main()
+
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/giet_xml/xml_parser.c
===================================================================
--- /branch/giet_vm_ioc_drivers/giet_xml/xml_parser.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/giet_xml/xml_parser.c	(revision 283)
@@ -0,0 +1,2856 @@
+///////////////////////////////////////////////////////////////////////////////////////
+// File     : xml_parser.c
+// Date     : 14/04/2012
+// Author   : alain greiner
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////////
+// This program translate a "map.xml" source file to a binary file "map.bin" that 
+// can be directly loaded in memory and used by the GIET-VM operating system.
+//
+// This map.xml file contains :
+// 1) the multi-cluster/multi-processors hardware architecture description
+// 2) the various multi-threaded software applications
+// 3) the mapping directives bor both the tasks and the virtual segments.
+// The corresponding C structures are defined in the "mapping_info.h" file.
+// 
+// This parser also generates the "hard_config.h" and the "giet_vsegs.ld" files,
+// required  to compile the GIET-VM code. 
+///////////////////////////////////////////////////////////////////////////////////////
+
+#include  <stdlib.h>
+#include  <fcntl.h>
+#include  <sys/types.h>
+#include  <sys/stat.h>
+#include  <unistd.h>
+#include  <stdio.h>
+#include  <string.h>
+#include  <assert.h>
+#include  <libxml/xmlreader.h>
+#include  <mapping_info.h>
+#include  <irq_handler.h>
+
+#define MAX_CLUSTERS   1024
+#define MAX_PSEGS      4096
+#define MAX_VSPACES    1024
+#define MAX_TASKS      4096
+#define MAX_MWMRS      4096
+#define MAX_VSEGS      4096
+#define MAX_VOBJS      8192
+#define MAX_PROCS      1024
+#define MAX_IRQS       8192
+#define MAX_COPROCS    4096
+#define MAX_CP_PORTS   8192
+#define MAX_PERIPHS    8192
+
+#define XML_PARSER_DEBUG  0
+
+///////////////////////////////////////////////////////////////////////////////////
+//     global variables used to store and index the data structures
+///////////////////////////////////////////////////////////////////////////////////
+
+mapping_header_t *   header;
+mapping_cluster_t *  cluster[MAX_CLUSTERS];  // cluster array
+mapping_pseg_t *     pseg[MAX_PSEGS];        // pseg array
+mapping_vspace_t *   vspace[MAX_VSPACES];    // vspace array
+mapping_vseg_t *     vseg[MAX_VSEGS];        // vseg array
+mapping_vobj_t *     vobj[MAX_VOBJS];        // vobj array
+mapping_task_t *     task[MAX_TASKS];        // task array
+mapping_proc_t *     proc[MAX_PROCS];        // proc array
+mapping_irq_t *      irq[MAX_IRQS];          // irq array
+mapping_coproc_t *   coproc[MAX_COPROCS];    // coproc array
+mapping_cp_port_t *  cp_port[MAX_CP_PORTS];  // coproc port array
+mapping_periph_t *   periph[MAX_PERIPHS];    // peripheral array
+
+// Index for the various arrays
+
+unsigned int cluster_index  = 0;
+unsigned int vspace_index = 0;
+unsigned int global_index = 0;
+unsigned int pseg_index = 0;        
+
+unsigned int proc_index = 0;
+unsigned int proc_loc_index = 0;
+
+unsigned int irq_index = 0;
+unsigned int irq_loc_index  = 0;
+
+unsigned int coproc_index = 0;
+unsigned int coproc_loc_index = 0;
+
+unsigned int cp_port_index = 0;
+unsigned int cp_port_loc_index = 0;
+
+unsigned int periph_index = 0;
+unsigned int periph_loc_index = 0;
+
+unsigned int vseg_index = 0;
+unsigned int vseg_loc_index = 0;
+
+unsigned int task_index = 0;
+unsigned int task_loc_index = 0;
+
+unsigned int vobj_index = 0;
+unsigned int vobj_loc_index = 0;
+unsigned int vobj_count = 0;
+
+
+//////////////////////////////
+// for replicated peripheral
+//////////////////////////////
+char found_timer = 0;
+char found_icu   = 0;
+char found_xcu   = 0;
+char found_dma   = 0;
+char found_mmc   = 0;
+
+
+////////////////////////////////////////////////////////////////////
+// These variables are used to generate the hard_config.h file
+////////////////////////////////////////////////////////////////////
+
+unsigned int nb_proc_max      = 0; // max number of processors per cluster
+unsigned int nb_tasks_max     = 0; // max number of tasks (in all vspaces)
+
+unsigned int tim_channels     = 0; // max number of user timers (per cluster)
+unsigned int dma_channels     = 0; // max number of DMA channels (per cluster)
+
+unsigned int icu_channels     = 0; // total number of IRQ per processor
+unsigned int tty_channels     = 0; // total number of terminals in TTY 
+unsigned int hba_channels     = 0; // total number of channels  in HBA
+unsigned int nic_channels     = 0; // total number of channels  in NIC 
+unsigned int cma_channels     = 0; // total number of channels  in CMA
+
+unsigned int use_iob          = 0; // using IOB component
+unsigned int use_xcu          = 0; // using XCU (not ICU)
+
+// These variables define the IOC peripheral subtype
+unsigned int use_hba          = 0; // using HBA
+unsigned int use_bdv          = 0; // using SoCLIB block device
+unsigned int use_spi          = 0; // using SD Card-SPI
+
+
+////////////////////////////////////////////////////////////////
+// These variables are used to generate the giet_vseg.ld file
+////////////////////////////////////////////////////////////////
+
+unsigned int periph_vbase_array[PERIPH_TYPE_MAX_VALUE] 
+         = { [0 ... (PERIPH_TYPE_MAX_VALUE - 1)] = 0xFFFFFFFF };
+
+//////////////////////////////////////////////////////////////////////
+// This arrray is useful to build a temporary list of vobj references. 
+// The struct vobj_ref_s is formed by a vspace_name and a vobj_name.
+// This array is used to set the attribute vobj_id of a cp_port
+// once all the vspace have been parsed.
+/////////////////////////////////////////////////////////////////////
+typedef struct vobj_ref_s 
+{
+    char vspace_name[32];
+    char vobj_name[32];
+} vobj_ref_t;
+
+vobj_ref_t * cp_port_vobj_ref[MAX_CP_PORTS];    
+
+
+//////////////////////////////////////////////////
+unsigned int getIntValue( xmlTextReaderPtr reader, 
+                          const char * attributeName, 
+                          unsigned int * ok) 
+{
+    unsigned int value = 0;
+    unsigned int i;
+    char c;
+
+    char * string = (char *) xmlTextReaderGetAttribute(reader, 
+                                (const xmlChar *) attributeName);
+
+    if (string == NULL) 
+    {
+        // missing argument
+        *ok = 0;
+        return 0;
+    }
+    else 
+    {
+        if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) 
+        {
+            // Hexa
+            for (i = 2 ; (string[i] != 0) && (i < 10) ; i++) 
+            {
+                c = string[i];
+                if      ((c >= '0') && (c <= '9')) { value = (value << 4) + string[i] - 48; }
+                else if ((c >= 'a') && (c <= 'f')) { value = (value << 4) + string[i] - 87; }
+                else if ((c >= 'A') && (c <= 'F')) { value = (value << 4) + string[i] - 55; }
+                else 
+                {
+                    *ok = 0;
+                    return 0;
+                }
+            }
+        }
+        else 
+        {
+            // Decimal
+            for (i = 0; (string[i] != 0) && (i < 9); i++) 
+            {
+                c = string[i];
+                if ((c >= '0') && (c <= '9')) value = (value * 10) + string[i] - 48;
+                else 
+                {
+                    *ok = 0;
+                    return 0;
+                }
+            }
+        }
+        *ok = 1;
+        return value; 
+    }
+} // end getIntValue()
+
+////////////////////////////////////////////////
+paddr_t getPaddrValue( xmlTextReaderPtr reader, 
+                       const char * attributeName, 
+                       unsigned int * ok) 
+{
+    paddr_t value = 0;
+    unsigned int i;
+    char c;
+
+    char * string = (char *) xmlTextReaderGetAttribute(reader, 
+                                (const xmlChar *) attributeName);
+
+    if (string == NULL) 
+    {
+        // missing argument
+        *ok = 0;
+        return 0;
+    }
+    else 
+    {
+        if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) 
+        {
+            // Hexa
+            for (i = 2 ; (string[i] != 0) && (i < 18) ; i++) 
+            {
+                c = string[i];
+                if      ((c >= '0') && (c <= '9')) { value = (value << 4) + string[i] - 48; }
+                else if ((c >= 'a') && (c <= 'f')) { value = (value << 4) + string[i] - 87; }
+                else if ((c >= 'A') && (c <= 'F')) { value = (value << 4) + string[i] - 55; }
+                else 
+                {
+                    *ok = 0;
+                    return 0;
+                }
+            }
+        }
+        else 
+        {
+            // Decimal not supported for paddr_t
+            *ok = 0;
+            return 0;
+        }
+        *ok = 1;
+        return value; 
+    }
+} // end getPaddrValue()
+
+////////////////////////////////////////////////
+char * getStringValue( xmlTextReaderPtr reader, 
+                       const char * attributeName, 
+                       unsigned int * ok ) 
+{
+    char * string = (char *) xmlTextReaderGetAttribute(reader, 
+                               (const xmlChar *) attributeName);
+
+
+    if (string == NULL) 
+    {
+        // missing argument
+        *ok = 0;
+        return NULL;
+    }
+    else 
+    {
+        //we read only string smaller than 32 byte
+        if (strlen(string) > 32) 
+        {
+            printf("[XML ERROR] all strings must be less than 32 bytes\n");
+            exit(1);
+        }
+
+        *ok = 1;
+        return string;
+    }
+} // end getStringValue()
+
+///////////////////////////////////////////////////////////////////////////////////
+// This function set the vbase address for all peripheral types. 
+// For replicated peripherals with the same type the virtual base address must be:
+//   vbase = seg_type_base & 0XFF000000 + 
+//          (cluster_id * vbase_cluster_increment) & 0x00FF0000
+///////////////////////////////////////////////////////////////////////////////////
+void set_periph_vbase_array()
+{
+    unsigned int vseg_id;      // vseg global index
+    unsigned int periph_id;    // periph global index
+    unsigned int pseg_id;      // pseg global index
+    unsigned int cluster_id;   // cluster linear index
+    unsigned int cluster_xy;   // cluster topological index
+    unsigned int type;         // peripheral type 
+
+    unsigned int type_mask    = 0xFF000000;
+    unsigned int cluster_mask = 0x00FF0000;
+
+    // We are analysing all vsegs corresponding to a peripheral
+
+    // scan all vsegs
+    for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++)
+    {
+        // keep only vseg corresponding to a periph        
+        if ( vobj[vseg[vseg_id]->vobj_offset]->type == VOBJ_TYPE_PERI )
+        {
+            pseg_id    = vseg[vseg_id]->psegid; 
+
+            // scan all periphs to retrieve peripheral type (same psegid)
+            for ( periph_id = 0 ; periph_id < header->periphs ; periph_id++)
+            {
+                if( periph[periph_id]->psegid == pseg_id ) // matching !!!
+                {
+                    type = periph[periph_id]->type;
+                    if ( periph_vbase_array[type] == 0xFFFFFFFF )  // vbase not set
+                    {
+                        periph_vbase_array[type] = vseg[vseg_id]->vbase & type_mask;    
+                    }
+                    else                                 // vbase already set
+                    {
+                        // checking mask bits 
+                        if( (vseg[vseg_id]->vbase & type_mask) != 
+                            (periph_vbase_array[type]) )
+                        {
+                            printf("[XML ERROR] All peripherals with same type ");
+                            printf(" should share the same 8 MSB bits in base address\n");
+                            printf("periph index = %d / periph type = %d / vbase = %x\n",
+                                    periph_id, type, vseg[vseg_id]->vbase);
+                            exit(1);
+                        }
+                    }
+   
+                    // checking cluster bits for all replicated peripherals
+                    if ( (type == PERIPH_TYPE_DMA) ||
+                         (type == PERIPH_TYPE_MMC) ||
+                         (type == PERIPH_TYPE_ICU) ||
+                         (type == PERIPH_TYPE_XCU) ||
+                         (type == PERIPH_TYPE_TIM) ) 
+                    {
+                        cluster_id = pseg[pseg_id]->clusterid;
+                        cluster_xy = (cluster[cluster_id]->x << header->y_width) +
+                                      cluster[cluster_id]->y;
+
+                        if( (vseg[vseg_id]->vbase & cluster_mask) != 
+                            (header->increment * cluster_xy) )
+                        {
+                            printf("[XML ERROR] All replicated peripherals ");
+                            printf("must have cluster bits = cluster_id * increment");
+                            printf("periph index = %d / periph type = %d / vbase = %x\n",
+                                    periph_id, type, vseg[vseg_id]->vbase);
+                            exit(1);
+                        }
+                    } 
+                }
+            }
+        }    
+    }
+}  // end set_periph_vbase_array()
+
+///////////////////////////////////////////////////////////////
+int getClusterId( unsigned int x, unsigned int y )
+{
+    // associative search of cluster index
+    unsigned int cluster_id;
+
+    for( cluster_id = 0 ; cluster_id < (header->x_size * header->y_size) ; cluster_id++ )
+    {
+        if( (cluster[cluster_id]->x == x) && (cluster[cluster_id]->y == y) )
+        {
+            return cluster_id;
+        }
+    }
+    return -1;
+}  // end getClusterId()
+
+///////////////////////////////////////////////////////////////
+int getPsegId(unsigned int x, unsigned int y, char * pseg_name) 
+{
+    int cluster_id = getClusterId( x, y );
+
+    if ( cluster_id == -1 ) return -1;
+
+    // associative search for pseg index
+    unsigned int pseg_id;
+    unsigned int pseg_min = cluster[cluster_id]->pseg_offset;
+    unsigned int pseg_max = pseg_min + cluster[cluster_id]->psegs;
+
+    for (pseg_id = pseg_min; pseg_id < pseg_max; pseg_id++) 
+    {
+        if (strcmp(pseg[pseg_id]->name, pseg_name) == 0) 
+        {
+            return pseg_id;
+        }
+    }
+    return -1;
+}  // end getPsegId()
+
+///////////////////////////////////
+int getVspaceId(char * vspace_name) 
+{
+    unsigned int vspace_id;
+
+    for (vspace_id = 0; vspace_id < vspace_index; vspace_id++) 
+    {
+        if (strcmp(vspace[vspace_id]->name, vspace_name) == 0) 
+        {
+            return vspace_id;
+        }
+    }
+    return -1;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+int getVobjLocId(unsigned int vspace_id, char * vobj_name, unsigned int vspace_max) 
+{
+    unsigned int vobj_id;
+    unsigned int vobj_min = vspace[vspace_id]->vobj_offset;
+    unsigned int vobj_max = vobj_min + vspace_max;
+
+    for (vobj_id = vobj_min; vobj_id < vobj_max; vobj_id++) 
+    {
+        if (strcmp(vobj[vobj_id]->name, vobj_name) == 0) return (vobj_id - vobj_min);
+    }
+    return -1;
+}
+
+//////////////////////////////////////
+void taskNode(xmlTextReaderPtr reader) 
+{
+    unsigned int ok;
+    unsigned int value;
+    unsigned int x,y;
+    char * str;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (task_index >= MAX_TASKS) 
+    {
+        printf("[XML ERROR] The number of tasks is larger than %d\n", MAX_TASKS);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+printf("   task %d\n", task_loc_index);
+#endif
+
+    task[task_index] = (mapping_task_t *) malloc(sizeof(mapping_task_t));
+
+    ////////// get name attribute
+    str = getStringValue(reader, "name", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+printf("      name      = %s\n", str);
+#endif
+        strncpy( task[task_index]->name, str, 31 );
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <name> attribute for task (%d,%d)\n", 
+                vspace_index, task_loc_index);
+        exit(1);
+    }
+
+    ///////// get x coordinate 
+    task[task_index]->trdid = getIntValue(reader, "trdid", &ok);
+#if XML_PARSER_DEBUG
+printf("      x         = %d\n", x);
+#endif
+    if ( !ok ) 
+    {
+        task[task_index]->trdid = task_loc_index;
+        printf("[XML WARNING] missing trdid (thread index) attribute "
+               "for task in vspace %d. Using value %d\n"
+               , vspace_index, task_loc_index);
+    }  
+
+    ///////// get x coordinate 
+    x = getIntValue(reader, "x", &ok);
+#if XML_PARSER_DEBUG
+printf("      x         = %d\n", x);
+#endif
+    if ( !(ok && (x < header->x_size)) ) 
+    {
+        printf("[XML ERROR] illegal or missing < x > attribute for task (%d,%d)\n",
+                vspace_index, task_loc_index);
+        exit(1);
+    }  
+
+    ///////// get y coordinate 
+    y = getIntValue(reader, "y", &ok);
+#if XML_PARSER_DEBUG
+printf("      y         = %d\n", y);
+#endif
+    if ( !(ok && (y < header->y_size)) ) 
+    {
+        printf("[XML ERROR] illegal or missing < y > attribute for task (%d,%d)\n",
+                vspace_index, task_loc_index);
+        exit(1);
+    }  
+
+    ///////// set clusterid attribute
+    int index = getClusterId( x, y );
+#if XML_PARSER_DEBUG
+printf("      clusterid = %d\n", index);
+#endif
+    if( index >= 0 )
+    {
+        task[task_index]->clusterid = index;
+    }
+    else
+    {
+        printf("[XML ERROR] <clusterid> not found for task (%d,%d)\n",
+                vspace_index, task_loc_index);
+        exit(1);
+    }
+
+    ////////// get proclocid attribute
+    value = getIntValue(reader, "proclocid", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+printf("      proclocid = %x\n", value);
+#endif
+        if (value >= cluster[task[task_index]->clusterid]->procs) 
+        {
+            printf("[XML ERROR] <proclocid> too large for task (%d,%d)\n",
+                    vspace_index, task_loc_index);
+            exit(1);
+        }
+        task[task_index]->proclocid = value;
+    }  
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <locprocid> attribute for task (%d,%d)\n", 
+                vspace_index, task_loc_index);
+        exit(1);
+    }
+
+    ////////// get stackname attribute
+    str = getStringValue(reader, "stackname" , &ok);
+    if (ok) 
+    {
+        int index = getVobjLocId(vspace_index, str , vobj_loc_index);
+        if (index >= 0) 
+        {
+#if XML_PARSER_DEBUG
+printf("      stackname = %s\n", str);
+printf("      stackid   = %d\n", index);
+#endif
+            task[task_index]->stack_vobjid = index;
+        }
+        else 
+        {
+            printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n", 
+                    vspace_index, task_loc_index);
+            exit(1);
+        }
+    }  
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n", 
+                vspace_index, task_loc_index);
+        exit(1);
+    }
+
+    ////////// get heap attribute
+    str = getStringValue(reader, "heapname", &ok);
+    if (ok) 
+    {
+        int index = getVobjLocId(vspace_index, str, vobj_loc_index);
+        if (index >= 0) 
+        {
+#if XML_PARSER_DEBUG
+printf("      heapname  = %s\n", str);
+printf("      heapid    = %d\n", index);
+#endif
+            task[task_index]->heap_vobjid = index;
+        }
+        else 
+        {
+            printf("[XML ERROR] illegal or missing <heapname> for task (%d,%d)\n", 
+                   vspace_index, task_loc_index);
+            exit(1);
+        }
+    }  
+    else 
+    {
+        task[task_index]->heap_vobjid = -1;
+    }
+
+    ////////// get startid  attribute
+    value = getIntValue(reader, "startid", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+printf("      startid   = %x\n", value);
+#endif
+        task[task_index]->startid = value;
+    }  
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <startid> attribute for task (%d,%d)\n", 
+                vspace_index, task_loc_index);
+        exit(1);
+    }
+
+    /////////// get use_tty  attribute (optionnal : 0 if missing)
+    value = getIntValue(reader, "usetty", &ok);
+#if XML_PARSER_DEBUG
+printf("      usetty = %x\n", value);
+#endif
+    task[task_index]->use_tty = (ok)? value : 0;
+
+    /////////// get use_nic  attribute (optionnal : 0 if missing)
+    value = getIntValue(reader, "usenic", &ok);
+#if XML_PARSER_DEBUG
+printf("      usenic = %x\n", value);
+#endif
+    task[task_index]->use_nic = (ok)? value : 0;
+
+    /////////// get use_tim attribute (optionnal : 0 if missing)
+    value = getIntValue(reader, "usetim", &ok);
+#if XML_PARSER_DEBUG
+printf("      usetim = %x\n", value);
+#endif
+    task[task_index]->use_tim = (ok)? value : 0;
+
+    /////////// get use_hba  attribute (optionnal : 0 if missing)
+    value = getIntValue(reader, "usehba", &ok);
+#if XML_PARSER_DEBUG
+printf("      usehba = %x\n", value);
+#endif
+    task[task_index]->use_hba = (ok)? value : 0;
+
+    /////////// get usecma  attribute (optionnal : 0 if missing)
+    value = getIntValue(reader, "usecma", &ok);
+#if XML_PARSER_DEBUG
+printf("      usecma = %x\n", value);
+#endif
+    task[task_index]->use_cma = (ok)? value : 0;
+
+    task_index++;
+    task_loc_index++;
+} // end taskNode()
+
+//////////////////////////////////////
+void vobjNode(xmlTextReaderPtr reader) 
+{
+    unsigned int ok;
+    unsigned int value;
+    char * str;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (vobj_index >= MAX_VOBJS) 
+    {
+        printf("[XML ERROR] The number of vobjs is larger than %d\n", MAX_VOBJS);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+printf("      vobj %d\n", vobj_loc_index);
+#endif
+
+    vobj[vobj_index] = (mapping_vobj_t *) malloc(sizeof(mapping_vobj_t));
+
+    ///////// get name attribute
+    str = getStringValue(reader, "name", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+printf("        name = %s\n", str);
+#endif
+        strncpy(vobj[vobj_index]->name, str, 31);
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <name> attribute for vobj (%d,%d)\n", 
+                vseg_index, vobj_loc_index);
+        exit(1);
+    }
+
+    //////// get type attribute
+    str = getStringValue(reader, "type", &ok);
+#if XML_PARSER_DEBUG
+printf("        type = %s\n", str);
+#endif
+
+    if      (ok && (strcmp(str, "ELF")      == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_ELF;      }
+    else if (ok && (strcmp(str, "PERI")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PERI;     }
+    else if (ok && (strcmp(str, "BLOB")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BLOB;     }
+    else if (ok && (strcmp(str, "PTAB")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PTAB;     }
+    else if (ok && (strcmp(str, "MWMR")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MWMR;     }
+    else if (ok && (strcmp(str, "LOCK")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_LOCK;     }
+    else if (ok && (strcmp(str, "BUFFER")   == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BUFFER;   }
+    else if (ok && (strcmp(str, "BARRIER")  == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BARRIER;  }
+    else if (ok && (strcmp(str, "CONST")    == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_CONST;    }
+    else if (ok && (strcmp(str, "MEMSPACE") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MEMSPACE; }
+    else if (ok && (strcmp(str, "SCHED")    == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_SCHED;    }
+    else if (ok && (strcmp(str, "BOOT")     == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BOOT;    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <type> attribute for vobj (%d,%d)\n", 
+                vspace_index, vobj_loc_index);
+        exit(1);
+    }
+    // some more checking
+    if ( (vobj[vobj_index]->type == VOBJ_TYPE_ELF) ||
+         (vobj[vobj_index]->type == VOBJ_TYPE_PERI) )
+    {
+        assert( (vobj_count == 0) && 
+        "[XML ERROR] an ELF or PERI vobj must be alone in a vseg");
+    }
+        
+
+    ////////// get length attribute 
+    value = getIntValue(reader, "length", &ok);
+    if (ok) {
+#if XML_PARSER_DEBUG
+printf("        length = %d\n", value);
+#endif
+        vobj[vobj_index]->length = value;
+    }  
+    else {
+        printf("[XML ERROR] illegal or missing <length> attribute for vobj (%d,%d)\n", 
+                vspace_index, vobj_loc_index);
+        exit(1);
+    }
+
+    ////////// get align attribute (optional : 0 if missing)
+    value = getIntValue(reader, "align", &ok);
+    if (ok) {
+#if XML_PARSER_DEBUG
+printf("        align = %d\n", value);
+#endif
+        vobj[vobj_index]->align = value;
+    }  
+    else {
+        vobj[vobj_index]->align = 0;
+    }
+
+    ////////// get binpath attribute (optional : '\0' if missing)
+    str = getStringValue(reader, "binpath", &ok);
+    if (ok) {
+#if XML_PARSER_DEBUG
+printf("        binpath = %s\n", str);
+#endif
+        strncpy(vobj[vobj_index]->binpath, str, 63);
+    }  
+    else {
+        vobj[vobj_index]->binpath[0] = '\0';
+    }
+
+    ////////// get init attribute (mandatory for mwmr and barrier)
+    value = getIntValue(reader, "init", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+printf("        init  = %d\n", value);
+#endif
+        vobj[vobj_index]->init = value;
+    }  
+    else 
+    {
+        if ((vobj[vobj_index]->type == VOBJ_TYPE_MWMR) || 
+            (vobj[vobj_index]->type == VOBJ_TYPE_BARRIER) ||
+            (vobj[vobj_index]->type == VOBJ_TYPE_CONST)) 
+        {
+            printf("[XML ERROR] illegal or missing <value> attribute for vobj (%d,%d). \
+                    All MWMR or BARRIER or CONST vobj must have a init value \n", 
+                    vspace_index, vobj_loc_index);
+            exit(1);
+        }
+        vobj[vobj_index]->init = 0;
+    }
+
+    vobj_index++;
+    vobj_count++;
+    vobj_loc_index++;
+} // end vobjNode()
+
+//////////////////////////////////////
+void vsegNode(xmlTextReaderPtr reader) 
+{
+    unsigned int ok;
+    unsigned int value;
+    unsigned int x,y;
+    char * str;
+
+    vobj_count = 0;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (vseg_index >= MAX_VSEGS) 
+    {
+        printf("[XML ERROR] The number of vsegs is larger than %d\n", MAX_VSEGS);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+printf("    vseg %d\n", vseg_loc_index);
+#endif
+
+    vseg[vseg_index] = (mapping_vseg_t *) malloc(sizeof(mapping_vseg_t));
+
+    ////////// set vobj_offset attributes
+    vseg[vseg_index]->vobj_offset = vobj_index;
+
+#if XML_PARSER_DEBUG
+printf("      vobj_offset = %d\n", vobj_index);
+#endif
+
+    ///////// set mapped attribute
+    vseg[vseg_index]->mapped = 0;
+
+    //////// set next_vseg attribute
+    vseg[vseg_index]->next_vseg = 0;
+  
+    ///////// get name attribute
+    str = getStringValue(reader, "name", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+printf("      name        = %s\n", str);
+#endif
+        strncpy( vseg[vseg_index]->name, str, 31);
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <name> attribute for vseg (%d,%d)\n", 
+                vspace_index, vseg_loc_index);
+        exit(1);
+    }
+
+    ////////// get ident attribute (optional : 0 if missing)
+    value = getIntValue(reader, "ident", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+printf("      ident       = %d\n", value);
+#endif
+        vseg[vseg_index]->ident = value;
+    }  
+    else 
+    {
+        vseg[vseg_index]->ident = 0;
+    }
+
+    /////////// get vbase attribute
+    value = getIntValue(reader, "vbase", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+printf("      vbase       = 0x%x\n", value);
+#endif
+        vseg[vseg_index]->vbase = value;
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <vbase> attribute for vseg (%d,%d)\n", 
+                vspace_index, vseg_loc_index);
+        exit(1);
+    }
+
+    ////////// get x coordinate
+    x = getIntValue(reader, "x", &ok);
+#if XML_PARSER_DEBUG
+printf("      x           = %d\n", x);
+#endif
+    if ( !(ok && (x < header->x_size)) ) 
+    {
+        printf("[XML ERROR] illegal or missing < x > attribute for vseg %d\n", 
+                vseg_loc_index);
+        exit(1);
+    }
+
+    ////////// get y coordinate
+    y = getIntValue(reader, "y", &ok);
+#if XML_PARSER_DEBUG
+printf("      y           = %d\n", y);
+#endif
+    if ( !(ok && (y < header->y_size)) ) 
+    {
+        printf("[XML ERROR] illegal or missing < y > attribute for vseg %d\n", 
+                vseg_loc_index);
+        exit(1);
+    }
+
+    ///////// get psegname attribute
+    str = getStringValue(reader, "psegname", &ok);
+#if XML_PARSER_DEBUG
+printf("      psegname    = %s\n", str);
+#endif
+    if (ok == 0) 
+    {
+        printf("[XML ERROR] illegal or missing <psegname> for vseg %d\n", 
+                vseg_loc_index);
+        exit(1);
+    }
+
+    /////////// set psegid field
+    int psegid = getPsegId( x, y, str );
+#if XML_PARSER_DEBUG
+printf("      psegid      = %d\n", psegid);
+#endif
+    if (index >= 0) 
+    {
+        vseg[vseg_index]->psegid = psegid;
+    }
+    else 
+    {
+        printf("[XML ERROR] pseg not found for vseg %d / x = %d / y = %d / psegname = %s\n", 
+                vseg_loc_index, x, y, str );
+        exit(1);
+    }  
+
+    //////// get mode attribute
+    str = getStringValue(reader, "mode", &ok);
+#if XML_PARSER_DEBUG
+printf("      mode        = %s\n", str);
+#endif
+    if      (ok && (strcmp(str, "CXWU") == 0)) { vseg[vseg_index]->mode = 0xF; }
+    else if (ok && (strcmp(str, "CXW_") == 0)) { vseg[vseg_index]->mode = 0xE; }
+    else if (ok && (strcmp(str, "CX_U") == 0)) { vseg[vseg_index]->mode = 0xD; }
+    else if (ok && (strcmp(str, "CX__") == 0)) { vseg[vseg_index]->mode = 0xC; }
+    else if (ok && (strcmp(str, "C_WU") == 0)) { vseg[vseg_index]->mode = 0xB; }
+    else if (ok && (strcmp(str, "C_W_") == 0)) { vseg[vseg_index]->mode = 0xA; }
+    else if (ok && (strcmp(str, "C__U") == 0)) { vseg[vseg_index]->mode = 0x9; }
+    else if (ok && (strcmp(str, "C___") == 0)) { vseg[vseg_index]->mode = 0x8; }
+    else if (ok && (strcmp(str, "_XWU") == 0)) { vseg[vseg_index]->mode = 0x7; }
+    else if (ok && (strcmp(str, "_XW_") == 0)) { vseg[vseg_index]->mode = 0x6; }
+    else if (ok && (strcmp(str, "_X_U") == 0)) { vseg[vseg_index]->mode = 0x5; }
+    else if (ok && (strcmp(str, "_X__") == 0)) { vseg[vseg_index]->mode = 0x4; }
+    else if (ok && (strcmp(str, "__WU") == 0)) { vseg[vseg_index]->mode = 0x3; }
+    else if (ok && (strcmp(str, "__W_") == 0)) { vseg[vseg_index]->mode = 0x2; }
+    else if (ok && (strcmp(str, "___U") == 0)) { vseg[vseg_index]->mode = 0x1; }
+    else if (ok && (strcmp(str, "____") == 0)) { vseg[vseg_index]->mode = 0x0; }
+    else {
+        printf("[XML ERROR] illegal or missing <mode> attribute for vseg (%d,%d)\n", 
+                vspace_index, vseg_loc_index);
+        exit(1);
+    }
+
+    ////////// get vobjs in vseg
+    int status = xmlTextReaderRead(reader);
+    while (status == 1) 
+    {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if      (strcmp(tag, "vobj")     == 0 ) { vobjNode(reader); }
+        else if (strcmp(tag, "#text"  )  == 0 ) { }
+        else if (strcmp(tag, "#comment") == 0 ) { }
+        else if (strcmp(tag, "vseg")     == 0 ) 
+        {
+            vseg[vseg_index]->vobjs = vobj_count;
+            vseg_index++;
+            vseg_loc_index++;
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag %s", tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead (reader);
+    }
+} // end vsegNode()
+
+////////////////////////////////////////
+void vspaceNode(xmlTextReaderPtr reader) 
+{
+    char * str;
+    unsigned int ok;
+    unsigned int nb_task_vspace = 0;
+
+    vobj_loc_index = 0;
+    vseg_loc_index = 0;
+    task_loc_index = 0;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    // checking source file consistency
+    if (vspace_index >= header->vspaces) {
+        printf("[XML ERROR] The vspace index is too large : %d\n", 
+                vspace_index);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+printf("\n  vspace %d\n", vspace_index);
+#endif
+
+    vspace[vspace_index] = (mapping_vspace_t *) malloc(sizeof(mapping_vspace_t));
+
+    ////////// get name attribute
+    str = getStringValue(reader, "name", &ok);
+    if (ok) {
+#if XML_PARSER_DEBUG
+printf("  name = %s\n", str);
+#endif
+        strncpy(vspace[vspace_index]->name, str, 31);
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <name> attribute for vspace %d\n", 
+                vspace_index);
+        exit(1);
+    }
+
+    ////////// set vseg_offset and task_offset attributes
+    vspace[vspace_index]->vseg_offset = vseg_index;
+    vspace[vspace_index]->vobj_offset = vobj_index;
+    vspace[vspace_index]->task_offset = task_index;
+
+#if XML_PARSER_DEBUG
+    printf("  vseg_offset = %d\n", vseg_index);
+    printf("  vobj_offset = %d\n", vobj_index);
+    printf("  task_offset = %d\n", task_index);
+#endif
+
+    ////////// get startname attribute
+    str = getStringValue(reader, "startname", &ok);
+    if (ok) {
+        //used after parsing the vobjs
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <startname> attribute for vspace %s\n", 
+                vspace[vspace_index]->name);
+        exit(1);
+    }
+
+    int status = xmlTextReaderRead(reader);
+    while (status == 1) {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if (strcmp(tag, "vseg") == 0) 
+        {
+            vsegNode(reader);
+        }
+        else if (strcmp(tag, "task") == 0) 
+        {
+            taskNode(reader);
+            nb_task_vspace++;
+        }
+        else if (strcmp(tag, "#text")    == 0) { }
+        else if (strcmp(tag, "#comment") == 0) { }
+        else if (strcmp(tag, "vspace")   == 0) {
+            vspace[vspace_index]->vobjs = vobj_loc_index; 
+            vspace[vspace_index]->tasks = task_loc_index ;
+            vspace[vspace_index]->vsegs = vseg_loc_index ;
+
+            // get index of the vobj containing the start vector
+            int index = getVobjLocId(vspace_index, str , vobj_loc_index);
+            if (index == -1) 
+            {
+                printf("[XML ERROR] vobj containing start vector not found in vspace %s\n",
+                        vspace[vspace_index]->name);
+                exit(1);
+            }
+            else 
+            {
+                vspace[vspace_index]->start_offset = index;
+#if XML_PARSER_DEBUG
+                printf("      startname = %s\n", str);
+                printf("      startid   = %d\n", index);
+                printf("  end vspace %d\n\n", vspace_index);
+#endif
+            }
+
+            // checking startid values for all tasks in vspace
+            int task_id;
+            int task_min = vspace[vspace_index]->task_offset;
+            int task_max = task_min + vspace[vspace_index]->tasks; 
+            for (task_id = task_min; task_id < task_max; task_id++) {
+                if (task[task_id]->startid >= vspace[vspace_index]->tasks) 
+                {
+                    printf("[XML ERROR] <startid> too large for task (%d,%d)\n", 
+                            vspace_index, task_id );
+                    exit(1);
+                }
+            }
+
+            nb_tasks_max += nb_task_vspace;
+            vspace_index++;
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag %s", tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead(reader);
+    }
+} // end vspaceNode()
+
+////////////////////////////////////////
+void cpPortNode(xmlTextReaderPtr reader) 
+{
+    char * str;
+    unsigned int ok;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (cp_port_index >= MAX_CP_PORTS) 
+    {
+        printf("[XML ERROR] The number of ports (for coprocs) is larger than %d\n", 
+                 MAX_CP_PORTS);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+    printf("\n  port %d\n", cp_port_index);
+#endif
+
+    cp_port[cp_port_index] = (mapping_cp_port_t *) malloc(sizeof(mapping_cp_port_t));
+    cp_port_vobj_ref[cp_port_index] = (vobj_ref_t *) malloc(sizeof(vobj_ref_t));
+
+    ///////// get direction attribute
+    str = getStringValue(reader, "direction", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("      direction = %s\n", str);
+#endif
+        if (strcmp(str, "TO_COPROC")   ==  0) 
+        {
+            cp_port[cp_port_index]->direction = PORT_TO_COPROC;
+        }
+        else if (strcmp(str, "FROM_COPROC") ==  0) 
+        {
+            cp_port[cp_port_index]->direction = PORT_FROM_COPROC;
+        }
+        else 
+        {
+            printf("[XML ERROR] illegal <direction> for cp_port %d in cluster %d\n",
+                    cp_port_index, cluster_index);
+            exit(1);
+        }
+    }  
+    else 
+    {
+        printf("[XML ERROR] missing <direction> for cp_port %d in cluster %d\n",
+                cp_port_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// get vspacename attribute 
+    str = getStringValue(reader, "vspacename", &ok);
+#if XML_PARSER_DEBUG
+    printf("      vspacename = %s\n", str);
+#endif
+    if (ok) 
+    {
+        strncpy(cp_port_vobj_ref[cp_port_index]->vspace_name, str, 31);
+    }
+    else 
+    {
+        printf("[XML ERROR] missing <vspacename> for cp_port %d in cluster %d\n",
+                cp_port_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// get vobjname attribute 
+    str = getStringValue(reader, "vobjname", &ok);
+#if XML_PARSER_DEBUG
+    printf("      vobjname = %s\n", str);
+#endif
+    if (ok) 
+    {
+        strncpy(cp_port_vobj_ref[cp_port_index]->vobj_name, str, 31);
+    }
+    else 
+    {
+        printf("[XML ERROR] missing <vobjname> for cp_port %d in cluster %d\n",
+                cp_port_index, cluster_index);
+        exit(1);
+    }
+    cp_port_index++;
+    cp_port_loc_index++;
+} // end cpPortNode()
+
+////////////////////////////////////////
+void periphNode(xmlTextReaderPtr reader) 
+{
+    char * str;
+    unsigned int value;
+    unsigned int ok;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (periph_index >= MAX_PERIPHS) 
+    {
+        printf("[XML ERROR] The number of periphs is larger than %d\n", MAX_PERIPHS);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+    printf("\n  periph %d\n", periph_index);
+#endif
+
+    periph[periph_index] = (mapping_periph_t *) malloc(sizeof(mapping_periph_t));
+
+    ///////// get channels attribute (optionnal : 1 if missing)
+    value = getIntValue(reader, "channels", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("      channels = %d\n", value);
+#endif
+        periph[periph_index]->channels = value;
+    }
+    else 
+    {
+        periph[periph_index]->channels = 1;
+    }
+
+    /////////// get psegname attribute 
+    str = getStringValue(reader, "psegname", &ok);
+    if (ok == 0) 
+    {
+        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 
+                coproc_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// set psegid attribute
+    int index = getPsegId( cluster[cluster_index]->x, cluster[cluster_index]->y, str);
+    if (index >= 0) 
+    {
+#if XML_PARSER_DEBUG
+        printf("      clusterid = %d\n", cluster_index);
+        printf("      psegname  = %s\n", str);
+        printf("      psegid    = %d\n", index);
+#endif
+        periph[periph_index]->psegid = index;
+    }
+    else 
+    {
+        printf("[XML ERROR] pseg not found for periph %d / clusterid = %d / psegname = %s\n", 
+                periph_loc_index, cluster_index, str );
+        exit(1);
+    }  
+
+    /////////// get type attribute 
+    str = getStringValue(reader, "type", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("      type      = %s\n", str);
+#endif
+        unsigned int error = 0;
+
+        // initialize peripheral subtype
+        periph[periph_index]->subtype = 0xFFFFFFFF;
+
+        // The CMA, FBF, HBA, IOB, IOC, NIC, ROM, SIM, TTY, peripherals are not 
+        // replicated in all clusters but can be replicated in two clusters (fault tolerance)
+        // In case of replication, the two copies must have same number of channels.
+
+        ////////////////////////////
+        if (strcmp(str, "CMA") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_CMA;
+            if (header->cma_cluster == 0xFFFFFFFF)  
+            {
+                header->cma_cluster = cluster_index;
+                cma_channels = periph[periph_index]->channels;
+            }
+            else if (header->cma_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->cma_cluster_bis = cluster_index;
+                assert( (cma_channels == periph[periph_index]->channels) &&
+                "[XML ERROR] unconsistent non replicated peripheral");
+            }
+            else  
+            {
+                error = 1;
+            }
+        }
+        /////////////////////////////////
+        else if (strcmp(str, "FBF") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_FBF;
+            if (header->fbf_cluster == 0xFFFFFFFF)  
+            {
+                header->fbf_cluster = cluster_index; 
+            }
+            else if (header->fbf_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->fbf_cluster_bis = cluster_index; 
+            }
+            else  
+            {
+                error = 1;
+            }
+        }
+        /////////////////////////////////
+        else if (strcmp(str, "HBA") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_HBA;
+            use_hba = 1;
+            if (header->hba_cluster == 0xFFFFFFFF)
+            {
+                header->hba_cluster  = cluster_index; 
+                hba_channels = periph[periph_index]->channels;
+            }
+            else if (header->hba_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->hba_cluster_bis = cluster_index;
+                assert( (hba_channels == periph[periph_index]->channels) &&
+                "[XML ERROR] unconsistent non replicated peripheral");
+            }
+            else
+            {
+                error = 1;
+            }
+        } 
+        /////////////////////////////////
+        else if (strcmp(str, "IOB") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_IOB;
+            use_iob = 1;
+            if (header->iob_cluster == 0xFFFFFFFF)  
+            {
+                header->iob_cluster = cluster_index; 
+            }
+            else if (header->iob_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->iob_cluster_bis = cluster_index; 
+            }
+            else  
+            {
+                error = 1;
+            }
+        }
+        /////////////////////////////////
+        else if (strcmp(str, "IOC") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_IOC;
+
+            if (header->ioc_cluster == 0xFFFFFFFF)
+            {
+                header->ioc_cluster  = cluster_index; 
+            }
+            else if (header->ioc_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->ioc_cluster_bis = cluster_index;
+            }
+            else
+            {
+                printf("[XML ERROR] At most two copies for non replicated "
+                        "peripheral\n");
+                exit(1);
+            }
+
+            str = getStringValue(reader, "subtype", &ok);
+    
+            if (!ok)
+            {
+                printf("[XML ERROR] IOC peripheral needs a subtype parameter: "
+                       "BDV, HBA or SPI\n");
+                exit(1);
+            } 
+
+            if (strcmp(str, "BDV") == 0)
+            { 
+                periph[periph_index]->subtype = PERIPH_SUBTYPE_BDV;
+                use_bdv = 1;
+            }
+            else if (strcmp(str, "HBA") == 0)
+            {
+                periph[periph_index]->subtype = PERIPH_SUBTYPE_HBA;
+
+                if (use_hba == 0)
+                {
+                    use_hba      = 1;
+                    hba_channels = periph[periph_index]->channels;
+                }
+                else
+                {
+                    assert( (hba_channels == periph[periph_index]->channels) &&
+                    "[XML ERROR] unconsistent non replicated peripheral");
+                }
+            }
+            else if (strcmp(str, "SPI") == 0)
+            {
+                periph[periph_index]->subtype = PERIPH_SUBTYPE_SPI;
+                use_spi = 1;
+            }
+            else
+            {
+                printf("[XML ERROR] illegal subtype for IOC peripheral\n");
+                exit(1);
+            }
+        } 
+        /////////////////////////////////
+        else if (strcmp(str, "NIC") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_NIC;
+            if (header->nic_cluster == 0xFFFFFFFF)  
+            {
+                header->nic_cluster = cluster_index;
+                nic_channels = periph[periph_index]->channels;
+            }
+            else if (header->nic_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->nic_cluster_bis = cluster_index;
+                assert( (nic_channels == periph[periph_index]->channels) &&
+                "[XML ERROR] unconsistent non replicated peripheral");
+            }
+            else  
+            {
+                error = 1;
+            }
+        }
+        /////////////////////////////////
+        else if (strcmp(str, "ROM") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_ROM;
+            if (header->rom_cluster == 0xFFFFFFFF)
+            {
+                header->rom_cluster  = cluster_index; 
+            }
+            else if (header->rom_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->rom_cluster_bis = cluster_index;
+            }
+            else
+            {
+                error = 1;
+            }
+        } 
+        /////////////////////////////////
+        else if (strcmp(str, "SIM") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_SIM;
+            if (header->sim_cluster == 0xFFFFFFFF)
+            {
+                header->sim_cluster  = cluster_index; 
+            }
+            else if (header->sim_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->sim_cluster_bis = cluster_index;
+            }
+            else
+            {
+                error = 1;
+            }
+        } 
+        /////////////////////////////////
+        else if (strcmp(str, "TTY") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_TTY;
+            if (header->tty_cluster == 0xFFFFFFFF) 
+            {
+                header->tty_cluster = cluster_index;
+                tty_channels = periph[periph_index]->channels;
+            }
+            else if (header->tty_cluster_bis == 0xFFFFFFFF) 
+            {
+                header->tty_cluster_bis = cluster_index;
+                assert( (tty_channels == periph[periph_index]->channels) &&
+                "[XML ERROR] unconsistent non replicated peripheral");
+            }
+            else  
+            {
+                error = 1;
+            }
+        }
+
+        // The DMA, ICU, MMC, TIM, XCU peripherals can be replicated in all clusters
+        // but it must exist only one component of each type per cluster
+
+        /////////////////////////////////
+        else if (strcmp(str, "DMA") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_DMA;
+            if (found_dma)  error = 1; 
+            found_dma = 1;
+            if (dma_channels < periph[periph_index]->channels)
+                dma_channels = periph[periph_index]->channels;
+        }
+        //////////////////////////////////
+        else if (strcmp(str, "ICU") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_ICU;
+            if (found_icu || use_xcu)  error = 1; 
+            found_icu = 1;
+
+            if (icu_channels > 0) 
+            {
+                assert( (periph[periph_index]->channels == icu_channels) &&
+                        "[XML ERROR] the number of interruptions per processor "
+                        "from the ICU (icu channels) must be the same on all "
+                        "clusters");
+            }
+            else
+            {
+                icu_channels = periph[periph_index]->channels;
+            }
+        }
+        //////////////////////////////////
+        else if (strcmp(str, "MMC") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_MMC;
+            if (found_mmc)  error = 1; 
+            found_mmc = 1;
+            if ( periph[periph_index]->channels != 1 ) error = 1;
+        }
+        //////////////////////////////////
+        else if (strcmp(str, "TIM") == 0 ) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_TIM;
+            if (found_timer || use_xcu)  error = 1; 
+            found_timer = 1;
+            if (tim_channels < periph[periph_index]->channels) 
+            {
+                tim_channels = periph[periph_index]->channels;
+            }
+        }
+        //////////////////////////////////
+        else if (strcmp(str, "XCU") == 0) 
+        {
+            periph[periph_index]->type = PERIPH_TYPE_XCU;
+            if (found_xcu || found_icu || found_timer)  error = 1; 
+            found_xcu    = 1;
+            found_timer  = 1;
+            tim_channels = 32; 
+            use_xcu      = 1;
+
+            if (icu_channels > 0) 
+            {
+                assert( (periph[periph_index]->channels == icu_channels) &&
+                        "[XML ERROR] the number of interruptions per processor "
+                        "from the ICU (icu channels) must be the same on all "
+                        "clusters");
+            }
+            else
+            {
+                icu_channels = periph[periph_index]->channels;
+            }
+        }
+        else 
+        {
+            printf("[XML ERROR] illegal <type>: %s for peripheral %d in cluster %d\n",
+                    str, periph_loc_index, cluster_index);
+            exit(1);
+        }
+
+        if (error) 
+        {
+            printf("[XML ERROR] illegal <type>: %s for peripheral %d in cluster %d\n",
+                    str, periph_loc_index, cluster_index);
+            exit(1);
+        }
+    }
+    else 
+    {
+        printf("[XML ERROR] missing <type> for peripheral  %d in cluster %d\n",
+                periph_loc_index, cluster_index);
+        exit(1);
+    }
+
+    periph_index++;
+    periph_loc_index++;
+    cluster[cluster_index]->periphs++;
+
+} // end periphNode
+
+////////////////////////////////////////
+void coprocNode(xmlTextReaderPtr reader) 
+{
+    char * str;
+    unsigned int ok;
+
+    cp_port_loc_index = 0;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (coproc_index >= MAX_COPROCS) 
+    {
+        printf("[XML ERROR] The number of coprocs is larger than %d\n", MAX_COPROCS);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+    printf("\n  coproc %d\n", coproc_index);
+#endif
+
+    coproc[coproc_index] = (mapping_coproc_t *) malloc(sizeof(mapping_coproc_t));
+
+    /////////// get name attribute 
+    str = getStringValue(reader, "name", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("      name = %s\n", str);
+#endif
+        strncpy(coproc[coproc_index]->name, str, 31);
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <name> for coproc %d in cluster %d\n",
+                coproc_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// get psegname attribute 
+    str = getStringValue(reader, "psegname", &ok);
+    if (ok == 0) 
+    {
+        printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 
+                coproc_index, cluster_index);
+        exit(1);
+    }
+
+    /////////// set psegid attribute
+    int index = getPsegId( cluster[cluster_index]->x, cluster[cluster_index]->y, str);
+    if (index >= 0) 
+    {
+#if XML_PARSER_DEBUG
+        printf("      clusterid = %d\n", cluster_index);
+        printf("      psegname  = %s\n", str);
+        printf("      psegid    = %d\n", index);
+#endif
+        coproc[coproc_index]->psegid = index;
+        assert(pseg[index]->type == PSEG_TYPE_PERI && "coproc psegname attribute must refer to a pseg of type PERI" );
+    }
+    else 
+    {
+        printf("[XML ERROR] pseg not found for coproc %d / clusterid = %d / psegname = %s\n", 
+                coproc_index, cluster_index, str );
+        exit(1);
+    }  
+
+    ////////// set port_offset 
+    coproc[coproc_index]->port_offset = cp_port_index;
+
+#if XML_PARSER_DEBUG
+    printf("      port_offset = %d\n", cp_port_index);
+#endif
+
+    int status = xmlTextReaderRead(reader);
+    while (status == 1) 
+    {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if (strcmp(tag, "port") == 0 ) 
+        {
+            cpPortNode(reader);
+        }
+        else if (strcmp(tag, "#text")    == 0 ) { }
+        else if (strcmp(tag, "#comment") == 0 ) { }
+        else if (strcmp(tag, "coproc") == 0 ) 
+        {
+            coproc[coproc_index]->ports = cp_port_loc_index;
+            cluster[cluster_index]->coprocs++;
+            coproc_loc_index++;
+            coproc_index++;
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag %s", tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead(reader);
+    }
+} // end coprocNode()
+
+
+/////////////////////////////////////
+void irqNode(xmlTextReaderPtr reader) 
+{
+    unsigned int ok;
+    unsigned int value;
+    char * str;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (irq_index >= MAX_IRQS) {
+        printf("[XML ERROR] The number of irqs is larger than %d\n", MAX_IRQS);
+    }
+
+#if XML_PARSER_DEBUG
+    printf("     irq %d\n", irq_loc_index);
+#endif
+
+    irq[irq_index] = (mapping_irq_t *) malloc(sizeof(mapping_irq_t));
+
+    ///////// get type attribute
+    str = getStringValue(reader, "type", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("        type    = %s\n", str);
+#endif
+        if      ( strcmp(str, "HARD") == 0 ) irq[irq_index]->type = IRQ_TYPE_HWI;
+        else if ( strcmp(str, "SOFT") == 0 ) irq[irq_index]->type = IRQ_TYPE_SWI;
+        else if ( strcmp(str, "TIME") == 0 ) irq[irq_index]->type = IRQ_TYPE_PTI;
+        else    
+        {
+            printf("[XML ERROR] illegal IRQ <type> for processor %d in cluster %d\n",
+                    cluster_index, proc_loc_index);
+            exit(1);
+        }
+    }
+    else 
+    {
+        printf("[XML ERROR] missing IRQ <type> for processor %d in cluster %d\n",
+                cluster_index, proc_loc_index);
+        exit(1);
+    }
+
+    ///////// get icuid attribute
+    value = getIntValue(reader, "icuid", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("        icuid   = %d\n", value);
+#endif
+        irq[irq_index]->icuid = value;
+        if (value >= 32) 
+        {
+            printf("[XML ERROR] IRQ <icuid> too large for processor %d in cluster %d\n",
+                    cluster_index, proc_loc_index);
+            exit(1);
+        }
+    }
+    else 
+    {
+        printf("[XML ERROR] missing IRQ <icuid> for processor %d in cluster %d\n",
+                cluster_index, proc_loc_index);
+        exit(1);
+    }
+
+    ///////// get isr attribute
+    str = getStringValue(reader, "isr", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("        isr     = %s\n", str);
+#endif
+        if      (strcmp(str, "ISR_SWITCH" ) == 0)  irq[irq_index]->isr = ISR_SWITCH;
+        else if (strcmp(str, "ISR_IOC"    ) == 0)  irq[irq_index]->isr = ISR_IOC;
+        else if (strcmp(str, "ISR_DMA"    ) == 0)  irq[irq_index]->isr = ISR_DMA;
+        else if (strcmp(str, "ISR_TTY"    ) == 0)  irq[irq_index]->isr = ISR_TTY;
+        else if (strcmp(str, "ISR_TIMER"  ) == 0)  irq[irq_index]->isr = ISR_TIMER;
+        else if (strcmp(str, "ISR_WAKUP"  ) == 0)  irq[irq_index]->isr = ISR_WAKUP;
+        else if (strcmp(str, "ISR_DEFAULT") == 0)  irq[irq_index]->isr = ISR_DEFAULT;
+        else 
+        {
+            printf("[XML ERROR] illegal IRQ <isr> for processor %d in cluster %d\n",
+                    cluster_index, proc_loc_index);
+            exit(1);
+        }
+#if XML_PARSER_DEBUG
+        printf("        isrnum  = %d\n", irq[irq_index]->isr);
+#endif
+    }  
+    else 
+    {
+        printf("[XML ERROR] missing IRQ <isr> for processor %d in cluster %d\n",
+                cluster_index, proc_loc_index);
+        exit(1);
+    }
+
+    ///////// get channel attribute (optionnal : 0 if missing)
+    value = getIntValue(reader, "channel", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("        channel = %d\n", value);
+#endif
+        irq[irq_index]->channel = value;
+    }
+    else 
+    {
+        irq[irq_index]->channel = 0;
+    }
+
+    irq_index++;
+    irq_loc_index++;
+
+} // end irqNode
+
+
+//////////////////////////////////////
+void procNode(xmlTextReaderPtr reader) 
+{
+    unsigned int ok;
+    unsigned int value;
+
+    irq_loc_index = 0;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (proc_index >= MAX_PROCS) 
+    {
+        printf("[XML ERROR] The number of procs is larger than %d\n", MAX_PROCS);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+    printf("\n  proc %d\n", proc_index);
+#endif
+
+    proc[proc_index] = (mapping_proc_t *) malloc(sizeof(mapping_proc_t));
+
+    /////////// get index attribute (optional)
+    value = getIntValue(reader, "index", &ok);
+    if (ok && (value != proc_loc_index)) 
+    {
+        printf("[XML ERROR] wrong proc index / expected value is %d", 
+                proc_loc_index);
+        exit(1);
+    }
+
+    ////////// set irq_offset attribute
+    proc[proc_index]->irq_offset = irq_index;
+
+#if XML_PARSER_DEBUG
+    printf("    irq_offset = %d\n", irq_index);
+#endif
+
+    int status = xmlTextReaderRead(reader);
+    while (status == 1) 
+    {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if (strcmp(tag, "irq") == 0) 
+        {
+            irqNode(reader);
+        }
+        else if (strcmp(tag, "#text")    == 0) { }
+        else if (strcmp(tag, "#comment") == 0) { }
+        else if (strcmp(tag, "proc")     == 0) 
+        {
+            proc[proc_index]->irqs = irq_loc_index;
+            cluster[cluster_index]->procs++;
+            proc_loc_index++;
+            proc_index++;
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag %s", tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead(reader);
+    }
+} // end procNode()
+
+
+//////////////////////////////////////
+void psegNode(xmlTextReaderPtr reader) 
+{
+    unsigned int ok;
+    paddr_t      ll_value;
+    char * str;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+    if (pseg_index >= MAX_PSEGS) 
+    {
+        printf("[XML ERROR] The number of psegs is larger than %d\n", MAX_PSEGS);
+        exit(1);
+    }
+
+#if XML_PARSER_DEBUG
+    printf("    pseg %d\n", pseg_index);
+#endif
+
+    pseg[pseg_index] = (mapping_pseg_t *) malloc(sizeof(mapping_pseg_t));
+
+    /////// get name attribute
+    str = getStringValue(reader, "name", &ok);
+#if XML_PARSER_DEBUG
+    printf("      name = %s\n", str);
+#endif
+    if (ok) 
+    {
+        strncpy(pseg[pseg_index]->name, str, 31);
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <name> for pseg %d in cluster %d\n",
+                pseg_index, cluster_index);
+        exit(1);
+    }
+
+    //////// get type attribute
+    str = getStringValue(reader, "type", &ok);
+#if XML_PARSER_DEBUG
+    printf("      type = %s\n", str);
+#endif
+    if      (ok && (strcmp(str, "RAM" ) == 0)) { pseg[pseg_index]->type = PSEG_TYPE_RAM; }
+    else if (ok && (strcmp(str, "ROM" ) == 0)) { pseg[pseg_index]->type = PSEG_TYPE_ROM; }
+    else if (ok && (strcmp(str, "PERI") == 0)) { pseg[pseg_index]->type = PSEG_TYPE_PERI; }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <type> for pseg %s in cluster %d\n",
+                pseg[pseg_index]->name, cluster_index);
+        exit(1);
+    }
+
+    //////// get base attribute
+    ll_value = getPaddrValue(reader, "base", &ok);
+#if XML_PARSER_DEBUG
+    printf("      base = 0x%llx\n", ll_value);
+#endif
+    if (ok) 
+    {
+        pseg[pseg_index]->base = ll_value;
+    }
+    else {
+        printf("[XML ERROR] illegal or missing <base> for pseg %s in cluster %d\n",
+                pseg[pseg_index]->name, cluster_index);
+        exit(1);
+    }
+
+    //////// get length attribute
+    ll_value = getPaddrValue(reader, "length", &ok);
+#if XML_PARSER_DEBUG
+    printf("      length = 0x%llx\n", ll_value);
+#endif
+    if (ok) 
+    {
+        pseg[pseg_index]->length = ll_value;
+    }  
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <length> for pseg %s in cluster %d\n",
+                pseg[pseg_index]->name, cluster_index);
+        exit(1);
+    }
+
+    //////// set cluster attribute
+    pseg[pseg_index]->clusterid = cluster_index;
+
+    //////// set next_vseg attribute
+    pseg[pseg_index]->next_vseg = 0;
+
+    pseg_index++;
+    cluster[cluster_index]->psegs++;
+} // end psegNode()
+
+
+/////////////////////////////////////////
+void clusterNode(xmlTextReaderPtr reader) 
+{
+    unsigned int ok;
+    unsigned int value;
+
+    cluster[cluster_index] = (mapping_cluster_t *) malloc(sizeof(mapping_cluster_t));
+
+    //initialise variables that will be incremented by *Node() functions
+    cluster[cluster_index]->psegs = 0;
+    cluster[cluster_index]->procs = 0;
+    cluster[cluster_index]->coprocs = 0;
+    cluster[cluster_index]->periphs = 0;
+
+    //initialise global variables
+    proc_loc_index = 0;
+    coproc_loc_index = 0;
+    periph_loc_index = 0;
+
+    // for replicated periph
+    found_timer = 0;
+    found_icu   = 0;
+    found_xcu   = 0;
+    found_dma   = 0;
+    found_mmc   = 0;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
+        return;
+    }
+
+#if XML_PARSER_DEBUG
+printf("\n  cluster %d\n", cluster_index);
+#endif
+
+    /////////// get x coordinate
+    value = getIntValue(reader, "x", &ok);
+#if XML_PARSER_DEBUG
+printf("    x             = %d\n", value);
+#endif
+    if (ok && (value < header->x_size) ) 
+    {
+        cluster[cluster_index]->x = value;
+    }
+    else
+    {
+        printf("[XML ERROR] Illegal or missing < x > attribute for cluster %d", 
+                cluster_index);
+        exit(1);
+    }
+
+    /////////// get y coordinate
+    value = getIntValue(reader, "y", &ok);
+#if XML_PARSER_DEBUG
+printf("    y             = %d\n", value);
+#endif
+    if (ok && (value < header->y_size) ) 
+    {
+        cluster[cluster_index]->y = value;
+    }
+    else
+    {
+        printf("[XML ERROR] Illegal or missing < y > attribute for cluster %d", 
+                cluster_index);
+        exit(1);
+    }
+
+    ////////// set offsets
+    cluster[cluster_index]->pseg_offset = pseg_index;
+    cluster[cluster_index]->proc_offset = proc_index;
+    cluster[cluster_index]->coproc_offset = coproc_index;
+    cluster[cluster_index]->periph_offset = periph_index;
+
+#if XML_PARSER_DEBUG
+printf("    pseg_offset   = %d\n", pseg_index);
+printf("    proc_offset   = %d\n", proc_index);
+printf("    coproc_offset = %d\n", coproc_index);
+printf("    periph_offset = %d\n", coproc_index);
+#endif
+
+    ////////// get psegs, procs, coprocs and periphs
+    int status = xmlTextReaderRead(reader);
+
+    while (status == 1) 
+    {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if      (strcmp(tag, "pseg")     == 0) psegNode(reader);
+        else if (strcmp(tag, "proc")     == 0) procNode(reader);
+        else if (strcmp(tag, "coproc")   == 0) coprocNode(reader);
+        else if (strcmp(tag, "periph")   == 0) periphNode(reader);
+        else if (strcmp(tag, "#text")    == 0) { }
+        else if (strcmp(tag, "#comment") == 0) { }
+        else if (strcmp(tag, "cluster")  == 0) 
+        {
+
+            ///////// TIMER and ICU peripheral are mandatory //////////////
+            if (!found_timer && !found_xcu)
+            {
+                printf("[XML ERROR] missing timer peripheral in cluster %d\n", cluster_index);
+                exit(1);
+            }
+
+            if (!found_icu && !found_xcu) 
+            {
+                printf("[XML ERROR] missing icu peripheral in cluster %d\n", cluster_index);
+                exit(1);
+            }
+
+            if (nb_proc_max < cluster[cluster_index]->procs) 
+            {
+                nb_proc_max = cluster[cluster_index]->procs;
+            }
+
+#if XML_PARSER_DEBUG
+printf("    psegs   = %d\n", cluster[cluster_index]->psegs);
+printf("    procs   = %d\n", cluster[cluster_index]->procs);
+printf("    coprocs = %d\n", cluster[cluster_index]->coprocs);
+printf("    periphs = %d\n", cluster[cluster_index]->periphs);
+printf("    end cluster %d\n", cluster_index);
+#endif
+            cluster_index++;
+            return;
+        }
+        status = xmlTextReaderRead(reader);
+    }
+} // end clusterNode()
+
+
+//////////////////////////////////////////////
+void clusterSetNode(xmlTextReaderPtr reader) 
+{
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+#if XML_PARSER_DEBUG
+printf("\n  clusters set\n");
+#endif
+
+    int status = xmlTextReaderRead(reader);
+    while (status == 1) 
+    {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if      (strcmp(tag, "cluster")    == 0) { clusterNode(reader); }
+        else if (strcmp(tag, "#text")      == 0) { }
+        else if (strcmp(tag, "#comment")   == 0) { }
+        else if (strcmp(tag, "clusterset") == 0) 
+        {
+            // checking source file consistency
+            if ( cluster_index != (header->x_size * header->y_size) ) 
+            {
+                printf("[XML ERROR] Wrong number of clusters\n");
+                exit(1);
+            }
+
+            // At least one TTY terminal for system boot
+            if (header->tty_cluster == 0xFFFFFFFF) 
+            {
+                printf("[XML ERROR] illegal or missing tty peripheral");
+                exit(1);
+            }
+
+#if XML_PARSER_DEBUG
+            printf("  end cluster set\n\n");
+#endif
+            header->psegs = pseg_index;
+            header->procs = proc_index;
+            header->irqs = irq_index;
+            header->coprocs = coproc_index;
+            header->cp_ports = cp_port_index;
+            header->periphs = periph_index;
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag in clusterset node : %s",tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead(reader);
+    }
+} // end clusterSetNode()
+
+
+///////////////////////////////////////////
+void globalSetNode(xmlTextReaderPtr reader) 
+{
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+#if XML_PARSER_DEBUG
+    printf("  globals set\n");
+#endif
+
+    int status = xmlTextReaderRead(reader);
+    while (status == 1) 
+    {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if      (strcmp(tag, "vseg")      == 0) { vsegNode(reader); }
+        else if (strcmp(tag, "#text")     == 0) { }
+        else if (strcmp(tag, "#comment")  == 0) { }
+        else if (strcmp(tag, "globalset") == 0) 
+        {
+#if XML_PARSER_DEBUG
+            printf("  end global set\n\n");
+#endif
+            header->globals = vseg_index;
+            vseg_loc_index = 0;
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag in globalset node : %s",tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead(reader);
+    }
+} // end globalSetNode()
+
+
+///////////////////////////////////////////
+void vspaceSetNode(xmlTextReaderPtr reader)
+{
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
+        return;
+    }
+
+#if XML_PARSER_DEBUG
+    printf("\n  vspaces set\n");
+#endif
+
+    int status = xmlTextReaderRead ( reader );
+    while (status == 1) {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if (strcmp(tag, "vspace") == 0) {
+            vspaceNode(reader);
+        }
+        else if (strcmp(tag, "#text"    ) == 0 ) { }
+        else if (strcmp(tag, "#comment" ) == 0 ) { }
+        else if (strcmp(tag, "vspaceset") == 0 ) 
+        {
+            // checking source file consistency
+            if (vspace_index != header->vspaces) 
+            {
+                printf("[XML ERROR] Wrong number of vspaces\n");
+                exit(1);
+            }
+            else 
+            {
+                header->vsegs = vseg_index;
+                header->vobjs = vobj_index;
+                header->tasks = task_index;
+                return;
+            }
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag in vspaceset node : %s",tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead(reader);
+    }
+} // end globalSetNode()
+
+
+////////////////////////////////////////
+void headerNode(xmlTextReaderPtr reader) 
+{
+    char * name;
+    unsigned int value;
+    unsigned int ok;
+
+    if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) return;
+
+#if XML_PARSER_DEBUG
+    printf("mapping_info\n");
+#endif
+
+    header = (mapping_header_t *) malloc(sizeof(mapping_header_t));
+
+    ////////// get name attribute
+    name = getStringValue(reader, "name", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  name = %s\n", name);
+#endif
+        strncpy( header->name, name, 31);
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <name> attribute in header\n");
+        exit(1);
+    }
+
+    /////////// get x_width attribute
+    value = getIntValue(reader, "x_width", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  x_width = %d\n", value);
+#endif
+        header->x_width = value;
+    }
+
+    /////////// get y_width attribute
+    value = getIntValue(reader, "y_width", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  y_width = %d\n", value);
+#endif
+        header->y_width = value;
+    }
+
+    /////////// get x_size attribute
+    unsigned int x_size = getIntValue(reader, "x_size", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  x_size  = %d\n", x_size);
+#endif
+        header->x_size = x_size;
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <x_size> attribute in header\n");
+        exit(1);
+    }
+
+    /////////// get y_size attribute
+    unsigned int y_size = getIntValue(reader, "y_size", &ok);
+    if (ok) 
+    {
+#if XML_PARSER_DEBUG
+        printf("  y_size  = %d\n", y_size);
+#endif
+        header->y_size = y_size;
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <y_size> attribute in header\n");
+        exit(1);
+    }
+
+    //check the number of cluster
+    if ( (x_size * y_size) >= MAX_CLUSTERS )
+    {
+        printf("[XML ERROR] Number of clusters cannot be larger than %d\n", MAX_CLUSTERS);
+        exit(1);
+    }
+
+    ///////// get vspaces attribute
+    value = getIntValue(reader, "vspaces", &ok);
+    if (ok) 
+    {
+        if (value >= MAX_VSPACES) 
+        {
+            printf("[XML ERROR] The number of vspaces is larger than %d\n", MAX_VSPACES);
+            exit(1);
+        }
+#if XML_PARSER_DEBUG
+        printf("  vspaces = %d\n", value);
+#endif
+        header->vspaces  = value;
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <vspaces> attribute in mapping\n");
+        exit(1);
+    }
+
+    ///////// get increment attribute
+    value = getIntValue(reader, "increment", &ok);
+    if (ok) 
+    {
+        if ( (value != 0x10000) && (value != 0x8000) &&
+             (value != 0x4000)  && (value != 0x2000) )
+       
+        {
+            printf("[XML ERROR] The vseg increment must be one of the following: ");
+            printf(" 0x00010000 / 0x00008000 / 0x00004000 / 0x00002000");
+            exit(1);
+        }
+#if XML_PARSER_DEBUG
+        printf("  increment = %d\n", value);
+#endif
+        header->increment  = value;
+    }
+    else 
+    {
+        printf("[XML ERROR] illegal or missing <increment> attribute in mapping\n");
+        exit(1);
+    }
+
+    //////// initialise non replicated peripherals cluster index
+    header->cma_cluster     = 0xFFFFFFFF;
+    header->cma_cluster_bis = 0xFFFFFFFF;
+
+    header->fbf_cluster     = 0xFFFFFFFF;
+    header->fbf_cluster_bis = 0xFFFFFFFF;
+
+    header->hba_cluster     = 0xFFFFFFFF;
+    header->hba_cluster_bis = 0xFFFFFFFF;
+
+    header->iob_cluster     = 0xFFFFFFFF;
+    header->iob_cluster_bis = 0xFFFFFFFF;
+
+    header->ioc_cluster     = 0xFFFFFFFF;
+    header->ioc_cluster_bis = 0xFFFFFFFF;
+
+    header->nic_cluster     = 0xFFFFFFFF;
+    header->nic_cluster_bis = 0xFFFFFFFF;
+
+    header->rom_cluster     = 0xFFFFFFFF;
+    header->rom_cluster_bis = 0xFFFFFFFF;
+
+    header->sim_cluster     = 0xFFFFFFFF;
+    header->sim_cluster_bis = 0xFFFFFFFF;
+
+    header->tty_cluster     = 0xFFFFFFFF;
+    header->tty_cluster_bis = 0xFFFFFFFF;
+
+    ///////// set signature
+    header->signature = IN_MAPPING_SIGNATURE;
+
+    int status = xmlTextReaderRead(reader);
+    while (status == 1) 
+    {
+        const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+        if (strcmp(tag, "clusterset") == 0) 
+        {
+            clusterSetNode(reader);
+        }
+        else if (strcmp(tag, "globalset")    == 0) { globalSetNode(reader); }
+        else if (strcmp(tag, "vspaceset")    == 0) { vspaceSetNode(reader); }
+        else if (strcmp(tag, "#text")        == 0) { }
+        else if (strcmp(tag, "#comment")     == 0) { }
+        else if (strcmp(tag, "mapping_info") == 0) 
+        {
+#if XML_PARSER_DEBUG
+            printf("end mapping_info\n");
+#endif
+            return;
+        }
+        else 
+        {
+            printf("[XML ERROR] Unknown tag in header node : %s\n",tag);
+            exit(1);
+        }
+        status = xmlTextReaderRead(reader);
+    }
+} // end headerNode()
+
+
+///////////////////////////////////////
+void BuildTable(int fdout, const char * type, unsigned int nb_elem,
+                unsigned int elem_size, char ** table) 
+{
+    unsigned int i;
+    // write element
+    for (i = 0; i < nb_elem; i++) {
+        if (elem_size != write(fdout, table[i], elem_size)) {
+            printf("function %s: %s(%d) write  error \n", __FUNCTION__, type, i);
+            exit(1);
+        }
+
+#if XML_PARSER_DEBUG
+        printf("Building binary: writing %s %d\n", type, i);
+#endif
+    }
+}
+
+/////////////////////////////////////
+int open_file(const char * file_path) 
+{
+    //open file
+    int fdout = open( file_path, (O_CREAT | O_RDWR), (S_IWUSR | S_IRUSR) );
+    if (fdout < 0) 
+    {
+        perror("open");
+        exit(1);
+    }
+
+    //reinitialise the file
+    if (ftruncate(fdout, 0)) 
+    {
+        perror("truncate");
+        exit(1);
+    }
+
+    //#if XML_PARSER_DEBUG
+    printf("%s\n", file_path);
+    //#endif
+
+    return fdout;
+}
+
+
+/////////////////////////////////////
+void buildBin(const char * file_path) 
+{
+    unsigned int length;
+
+    int fdout = open_file(file_path);
+
+#if XML_PARSER_DEBUG
+printf("Building map.bin for %s\n", header->name);
+printf("signature = %x\n", header->signature);
+printf("x_size    = %d\n", header->x_size);
+printf("y_size    = %d\n", header->y_size);
+printf("x_width   = %d\n", header->x_width);
+printf("y_width   = %d\n", header->y_width);
+printf("vspaces   = %d\n", header->vspaces);
+printf("psegs     = %d\n", header->psegs);
+printf("vobjs     = %d\n", header->vobjs);
+printf("vsegs     = %d\n", header->vsegs);
+printf("tasks     = %d\n", header->tasks);
+printf("procs     = %d\n", header->procs);
+printf("irqs      = %d\n", header->irqs);
+printf("coprocs   = %d\n", header->coprocs);
+printf("periphs   = %d\n", header->periphs);
+#endif
+
+    // write header to binary file
+    length = write(fdout, (char *) header, sizeof(mapping_header_t));
+    if (length != sizeof(mapping_header_t)) 
+    {
+        printf("write header error : length = %d \n", length);
+        exit(1);
+    }
+
+    // write clusters
+    BuildTable(fdout, "cluster", cluster_index, sizeof(mapping_cluster_t), (char **) cluster);
+    // write psegs
+    BuildTable(fdout, "pseg", pseg_index, sizeof(mapping_pseg_t), (char **) pseg);
+    // write vspaces
+    BuildTable(fdout, "vspace", vspace_index, sizeof(mapping_vspace_t), (char **) vspace);
+    // write vsegs
+    BuildTable(fdout, "vseg", vseg_index, sizeof(mapping_vseg_t), (char **) vseg);
+    // write vobjs
+    BuildTable(fdout, "vobj", vobj_index, sizeof(mapping_vobj_t), (char **) vobj);
+    // write tasks array
+    BuildTable(fdout, "task", task_index, sizeof(mapping_task_t), (char **) task);
+    //building procs array
+    BuildTable(fdout, "proc", proc_index, sizeof(mapping_proc_t), (char **) proc);
+    //building irqs array
+    BuildTable(fdout, "irq", irq_index, sizeof(mapping_irq_t), (char **) irq);
+    //building coprocs array
+    BuildTable(fdout, "coproc", coproc_index, sizeof(mapping_coproc_t), (char **) coproc);
+    //building cp_ports array
+    BuildTable(fdout, "cp_port", cp_port_index, sizeof(mapping_cp_port_t),(char **) cp_port);
+    //building periphs array
+    BuildTable(fdout, "periph", periph_index, sizeof(mapping_periph_t), (char **) periph);
+
+    close(fdout);
+
+} // end buildBin()
+
+
+///////////////////////////////////////////////////////////////////////
+// this function set the value the vobj_id fiels of all cp_ports
+///////////////////////////////////////////////////////////////////////
+void prepareBuild() 
+{
+    unsigned int i;
+    //asign for all cp_ports the correct vspaceid and vobjid
+    for (i = 0; i < cp_port_index; i++) {
+        int vspace_id = getVspaceId(cp_port_vobj_ref[i]->vspace_name);
+        if (vspace_id < 0) {
+            printf("[XML ERROR] illegal  <vspacename> for cp_port %d,\n", i);
+            exit(1);
+        }
+        cp_port[i]->vspaceid = vspace_id;
+
+        int vobj_id = getVobjLocId(vspace_id, cp_port_vobj_ref[i]->vobj_name, vspace[vspace_id]->vobjs);
+        if (vobj_id >= 0) {
+
+#if XML_PARSER_DEBUG
+            printf("\ncp_port = %d\n", i);
+            printf("      vspace_name  = %s\n", cp_port_vobj_ref[i]->vspace_name);
+            printf("      vobj_name    = %s\n", cp_port_vobj_ref[i]->vobj_name);
+            printf("      vobj_index   = %d\n", vobj_id);
+#endif
+            cp_port[i]->mwmr_vobjid = vobj_id;
+
+            assert((vobj[ vspace[vspace_id]->vobj_offset + vobj_id]->type == VOBJ_TYPE_MWMR)
+                    && "coproc ports have to refer to a vobj of type MWMR");
+        }
+        else {
+            printf("[XML ERROR] illegal  <vobjname> for cp_port %d,\n", i);
+            exit(1);
+        }
+    }
+}
+
+//////////////////////////////////////////
+void file_write(int fdout, char * towrite) 
+{
+    unsigned int size = strlen(towrite);
+    if (size != write(fdout, towrite, size)) 
+    {
+        printf("file_write error");
+        exit(1);
+    }
+}
+
+//////////////////////////////////////////////////
+void def_int_write(int fdout, char * def, int num) 
+{
+    char  buf[64];
+    sprintf(buf, "#define\t %s  %d\n", def, num);
+    file_write(fdout, buf);
+}
+
+//////////////////////////////////////////////////
+void def_hex_write(int fdout, char * def, int num) 
+{
+    char  buf[64];
+    sprintf(buf, "#define\t %s  0x%x\n", def, num);
+    file_write(fdout, buf);
+}
+
+///////////////////////////////////
+void  genHd(const char * file_path) 
+{
+    int fdout = open_file(file_path);
+
+    char prol[80];
+    sprintf(prol, "/* Generated from file %s.xml */\n\n",header->name);
+
+    char * ifdef  = "#ifndef _HARD_CONFIG_H\n#define _HARD_CONFIG_H\n\n";
+    char * epil   = "\n#endif //_HARD_CONFIG_H";
+
+    file_write(fdout, prol);
+    file_write(fdout, ifdef);
+
+    def_int_write(fdout, "X_SIZE            ", header->x_size);
+    def_int_write(fdout, "Y_SIZE            ", header->y_size);
+    def_int_write(fdout, "X_WIDTH           ", header->x_width);
+    def_int_write(fdout, "Y_WIDTH           ", header->y_width);
+
+    file_write(fdout, "\n");
+
+    def_int_write(fdout, "NB_PROCS_MAX      ", nb_proc_max);
+    def_int_write(fdout, "NB_TASKS_MAX      ", nb_tasks_max);
+
+    file_write(fdout, "\n");
+
+    def_int_write(fdout, "NB_TIM_CHANNELS   ", tim_channels);
+    def_int_write(fdout, "NB_DMA_CHANNELS   ", dma_channels);
+
+    file_write(fdout, "\n");
+
+    def_int_write(fdout, "NB_TTY_CHANNELS   ", tty_channels);
+    def_int_write(fdout, "NB_HBA_CHANNELS   ", hba_channels);
+    def_int_write(fdout, "NB_NIC_CHANNELS   ", nic_channels);
+    def_int_write(fdout, "NB_CMA_CHANNELS   ", cma_channels);
+
+    file_write(fdout, "\n");
+
+    def_int_write(fdout, "USE_XICU          ", use_xcu);
+    def_int_write(fdout, "USE_IOB           ", use_iob);
+    def_int_write(fdout, "USE_HBA           ", use_hba);
+    def_int_write(fdout, "USE_BDV           ", use_bdv);
+    def_int_write(fdout, "USE_SPI           ", use_spi);
+
+    file_write(fdout, "\n");
+
+    def_int_write(fdout, "IRQ_PER_PROCESSOR ", icu_channels);
+
+    file_write(fdout, epil);
+
+    close(fdout);
+}
+
+////////////////////////////////////////////////////////
+void ld_write(int fdout, char * seg, unsigned int addr) 
+{
+    char buf[64];
+    sprintf(buf, "%s = 0x%x;\n", seg, addr);
+    file_write(fdout, buf);
+}
+
+//////////////////////////////////
+void genLd(const char * file_path) 
+{
+    int          fdout = open_file(file_path);
+    unsigned int count = 0;
+    unsigned int vseg_id;
+    unsigned int base;      // vseg base
+    unsigned int size;      // vseg size
+
+    char prol[80];
+    sprintf(prol, "/* Generated from file %s.xml */\n\n",header->name);
+
+    file_write(fdout, prol);
+
+    // boot and kernel segments
+    for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++)
+    {
+        if ( strcmp(vseg[vseg_id]->name, "seg_boot_code") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_boot_code_base      ", base);
+            ld_write(fdout, "seg_boot_code_size      ", size);
+            count++;
+        }
+        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_data") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_boot_data_base      ", base);
+            ld_write(fdout, "seg_boot_data_size      ", size);
+            count++;
+        }
+        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_stack") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_boot_stack_base     ", base);
+            ld_write(fdout, "seg_boot_stack_size     ", size);
+            count++;        
+        }
+        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_mapping") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_boot_mapping_base   ", base);
+            ld_write(fdout, "seg_boot_mapping_size   ", size);
+            count++;
+        }
+        else if ( strcmp(vseg[vseg_id]->name, "seg_boot_buffer") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_boot_buffer_base    ", base);
+            ld_write(fdout, "seg_boot_buffer_size    ", size);
+            count++;
+        }
+        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_code") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_kernel_code_base    ", base);
+            ld_write(fdout, "seg_kernel_code_size    ", size);
+            count++;
+        }
+        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_data") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_kernel_data_base    ", base);
+            ld_write(fdout, "seg_kernel_data_size    ", size);
+            count++;
+        }
+        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_uncdata") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_kernel_uncdata_base ", base);
+            ld_write(fdout, "seg_kernel_uncdata_size ", size);
+            count++;
+        }
+        else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_init") == 0 )
+        {
+            base = vseg[vseg_id]->vbase;
+            size = vobj[vseg[vseg_id]->vobj_offset]->length;
+            ld_write(fdout, "seg_kernel_init_base    ", base);
+            ld_write(fdout, "seg_kernel_init_size    ", size);
+            count++;
+        }
+    }
+    if ( count != 9 )
+    { 
+        printf ("[XML ERROR] Missing Boot or Kernel vseg : only %d\n", count);
+        printf ("Mandatory segments are :\n");
+        printf (" - seg_boot_code\n");
+        printf (" - seg_boot_data\n");
+        printf (" - seg_boot_stack\n");
+        printf (" - seg_boot_mapping\n");
+        printf (" - seg_boot_buffer\n");
+        printf (" - seg_kernel_code\n");
+        printf (" - seg_kernel_data\n");
+        printf (" - seg_kernel_uncdata\n");
+        printf (" - seg_kernel_init\n");
+    }
+
+    file_write(fdout, "\n");
+
+    // fill the peripherals base address array 
+    set_periph_vbase_array();
+
+    // non replicated peripherals
+    ld_write(fdout, "seg_cma_base            ",   periph_vbase_array[PERIPH_TYPE_CMA]);
+    ld_write(fdout, "seg_fbf_base            ",   periph_vbase_array[PERIPH_TYPE_FBF]);
+    ld_write(fdout, "seg_hba_base            ",   periph_vbase_array[PERIPH_TYPE_HBA]);
+    ld_write(fdout, "seg_iob_base            ",   periph_vbase_array[PERIPH_TYPE_IOB]);
+    ld_write(fdout, "seg_ioc_base            ",   periph_vbase_array[PERIPH_TYPE_IOC]);
+    ld_write(fdout, "seg_nic_base            ",   periph_vbase_array[PERIPH_TYPE_NIC]);
+    ld_write(fdout, "seg_rom_base            ",   periph_vbase_array[PERIPH_TYPE_ROM]);
+    ld_write(fdout, "seg_sim_base            ",   periph_vbase_array[PERIPH_TYPE_SIM]);
+    ld_write(fdout, "seg_tty_base            ",   periph_vbase_array[PERIPH_TYPE_TTY]);
+
+    file_write(fdout, "\n");
+
+    // replicated peripherals
+    ld_write(fdout, "seg_dma_base            ",   periph_vbase_array[PERIPH_TYPE_DMA]);
+    ld_write(fdout, "seg_icu_base            ",   periph_vbase_array[PERIPH_TYPE_ICU]);
+    ld_write(fdout, "seg_mmc_base            ",   periph_vbase_array[PERIPH_TYPE_MMC]);
+    ld_write(fdout, "seg_tim_base            ",   periph_vbase_array[PERIPH_TYPE_TIM]);
+    ld_write(fdout, "seg_xcu_base            ",   periph_vbase_array[PERIPH_TYPE_XCU]);
+
+    file_write(fdout, "\n");
+
+    ld_write(fdout, "vseg_cluster_increment  ",   header->increment);
+
+    close(fdout);
+}
+
+//////////////////////////////////////////////////////
+char * buildPath(const char * path, const char * name) 
+{
+    char * res = calloc(strlen(path) + strlen(name) + 1, 1);
+    strcat(res, path);
+    strcat(res, "/");
+    strcat(res, name);
+    return res; 
+}
+
+
+//////////////////////////////////
+int main(int argc, char * argv[]) 
+{
+    if (argc < 3) {
+        printf("Usage: xml2bin <input_file_path> <output_path>\n");
+        return 1;
+    }
+
+    struct stat dir_st;
+    if (stat( argv[2], &dir_st)) {
+        perror("bad path");
+        exit(1);
+    }
+
+    if ((dir_st.st_mode & S_IFDIR) == 0) {
+        printf("path is not a dir: %s", argv[2] );
+        exit(1);
+    }
+
+    char * map_path = buildPath(argv[2], "map.bin"); 
+    char * ld_path = buildPath(argv[2], "giet_vsegs.ld"); 
+    char * hd_path = buildPath(argv[2], "hard_config.h"); 
+
+    LIBXML_TEST_VERSION;
+
+    int status;
+    xmlTextReaderPtr reader = xmlReaderForFile(argv[1], NULL, 0);
+
+    if (reader != NULL) 
+    {
+        status = xmlTextReaderRead (reader);
+        while (status == 1) 
+        {
+            const char * tag = (const char *) xmlTextReaderConstName(reader);
+
+            if (strcmp(tag, "mapping_info") == 0) 
+            { 
+                headerNode(reader);
+                prepareBuild();
+                buildBin(map_path);
+                genHd(hd_path);
+                genLd(ld_path);
+            }
+            else 
+            {
+                printf("[XML ERROR] Wrong file type: \"%s\"\n", argv[1]);
+                return 1;
+            }
+            status = xmlTextReaderRead(reader);
+        }
+        xmlFreeTextReader(reader);
+
+        if (status != 0) 
+        {
+            printf("[XML ERROR] Wrong Syntax in \"%s\" file\n", argv[1]);
+            return 1;
+        }
+    }
+    return 0;
+} // end main()
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/hdd/misc/batman.txt
===================================================================
--- /branch/giet_vm_ioc_drivers/hdd/misc/batman.txt	(revision 283)
+++ /branch/giet_vm_ioc_drivers/hdd/misc/batman.txt	(revision 283)
@@ -0,0 +1,19 @@
+*********************WB presents*****************************
+                                                             
+                                                             
+              _==/          i     i          \==             
+            /XX/            |\___/|            \XX\          
+          /XXXX\            |XXXXX|            /XXXX\        
+         |XXXXXX\_         _XXXXXXX_         _/XXXXXX|       
+        XXXXXXXXXXXxxxxxxxXXXXXXXXXXXxxxxxxxXXXXXXXXXXX      
+       |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|     
+       XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX     
+       |XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|     
+        XXXXXX/^^^^"\XXXXXXXXXXXXXXXXXXXXX/^^^^^\XXXXXX      
+         |XXX|       \XXX/^^\XXXXX/^^\XXX/       |XXX|       
+           \XX\       \X/    \XXX/    \X/       /XX/         
+              "\       "      \X/      "      /"             
+                                                             
+                                                             
+                                                             
+*****************That's all folks****************************
Index: /branch/giet_vm_ioc_drivers/hdd/misc/superman.txt
===================================================================
--- /branch/giet_vm_ioc_drivers/hdd/misc/superman.txt	(revision 283)
+++ /branch/giet_vm_ioc_drivers/hdd/misc/superman.txt	(revision 283)
@@ -0,0 +1,19 @@
+*********************WB presents*****************************
+                                                             
+             **************************                      
+          .*##*:*####***:::**###*:######*.                   
+         *##: .###*            *######:,##*                  
+       *##:  :####:             *####*.  :##:                
+        *##,:########**********:,       :##:                 
+         .#########################*,  *#*                   
+           *#########################*##:                    
+             *##,        ..,,::**#####:                      
+              ,##*,*****,        *##*                        
+                *#########*########:                         
+                  *##*:*******###*                           
+                   .##*.    ,##*                             
+                     :##*  *##,                              
+                       *####:                                
+                         :,                                  
+                                                             
+*****************That's all folks****************************
Index: /branch/giet_vm_ioc_drivers/hello/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/hello/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/hello/Makefile	(revision 283)
@@ -0,0 +1,24 @@
+APP_NAME=hello
+
+USE+= stdio.o
+
+USES=$(patsubst %,$(BUILD_PATH)/$(LIB_NAME)/%,$(USE))
+
+OBJS= main.o 
+
+all: $(APP_NAME).elf
+
+BIN_NAME_PATH=$(BUILD_PATH)$(APP_NAME).elf
+
+$(APP_NAME).elf: $(OBJS) $(APP_NAME).ld
+	$(LD) -o $(BIN_NAME_PATH) -T $(APP_NAME).ld $(OBJS) $(USES)
+	$(DU) -D $(BIN_NAME_PATH) > $@.txt
+
+%.o: %.c 
+	$(CC)  $(INCLUDE) $(CFLAGS) $($*.o_CFLAGS) -c -o  $@ $<
+	$(DU) -D  $@ >  $@.txt
+
+
+clean:
+	rm -f *.o *.elf *.txt core *~ 2>$(TRASH)
+	rm $(BIN_NAME_PATH) 2>$(TRASH)
Index: /branch/giet_vm_ioc_drivers/hello/hello.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/hello/hello.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/hello/hello.ld	(revision 283)
@@ -0,0 +1,39 @@
+/****************************************************************************
+* Definition of the base address for all virtual segments
+*****************************************************************************/
+
+seg_code_base      = 0x00400000;
+seg_data_base      = 0x00500000;	
+
+/***************************************************************************
+* Grouping sections into segments for code and data
+***************************************************************************/
+
+SECTIONS
+{
+    . = seg_code_base;
+    seg_code : 
+    {
+        *(.text)
+    }
+    . = seg_data_base;
+    seg_data : 
+    {
+        *(.ctors)
+        *(.rodata)
+        /* . = ALIGN(4); */
+        *(.rodata.*)
+        /* . = ALIGN(4); */
+        *(.data)
+        /* . = ALIGN(4); */
+        *(.lit8)
+        *(.lit4)
+        *(.sdata)
+        /* . = ALIGN(4); */
+        *(.bss)
+        *(COMMON)
+        *(.sbss)
+        *(.scommon)
+    }
+}
+
Index: /branch/giet_vm_ioc_drivers/hello/main.c
===================================================================
--- /branch/giet_vm_ioc_drivers/hello/main.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/hello/main.c	(revision 283)
@@ -0,0 +1,18 @@
+#include "stdio.h"
+
+__attribute__((constructor)) void main()
+{
+	char		    byte;
+    unsigned int	proc = giet_procid();
+
+    giet_tty_printf("Starting task HELLO on processor %d at cycle %d\n",
+                    giet_procid(), giet_proctime() );
+ 
+	while (1)
+	{
+		giet_tty_printf(" hello from processor %d\n", proc);
+        giet_tty_getc((void*)&byte);
+        if ( byte == 'q' ) giet_exit();
+	}
+} // end main
+
Index: /branch/giet_vm_ioc_drivers/mappings/1c_4p_40.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/1c_4p_40.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/1c_4p_40.xml	(revision 283)
@@ -0,0 +1,225 @@
+<?xml version="1.0"?>
+
+<mapping_info signature    = "0xdeadbeef" 
+              name         = "1c_4p_40" 
+              cluster_x    = "1" 
+              cluster_y    = "1" 
+              vspaces      = "4">
+
+*** This first section describes an instance of the "tsar_generic_xbar" architecture
+*** with 1 clusters, 4 processor per cluster and 40 bits physical address.
+
+    <clusterset>
+
+        <cluster index = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0010000000" />
+
+*** Boot ROM and peripherals
+
+			<pseg name = "PSEG_XICU" type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x00B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_FBF"  type = "PERI" base = "0x00B2000000" length = "0x0000004000" /> 
+            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00B3000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00B4000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_NIC"  type = "PERI" base = "0x00B5000000" length = "0x0000021000" />
+            <pseg name = "PSEG_CMA"  type = "PERI" base = "0x00B6000000" length = "0x0000004000" />
+            <pseg name = "PSEG_IOB"  type = "PERI" base = "0x00BE000000" length = "0x0000100000" />
+            <pseg name = "PSEG_ROM"  type = "ROM"  base = "0x00BFC00000" length = "0x0000100000" />
+
+            <proc index  = "0" >
+                <irq type = "HARD" icuid = "0"  isr = "ISR_SWITCH" /> 
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DMA" channel = "0" /> 
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY" channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY" channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY" channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY" channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY" channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY" channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY" channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY" channel = "7" /> 
+                <irq type = "HARD" icuid = "24" isr = "ISR_TTY" channel = "8" /> 
+                <irq type = "HARD" icuid = "25" isr = "ISR_TTY" channel = "9" />
+                <irq type = "HARD" icuid = "26" isr = "ISR_TTY" channel = "10" /> 
+                <irq type = "HARD" icuid = "27" isr = "ISR_TTY" channel = "11" /> 
+                <irq type = "HARD" icuid = "28" isr = "ISR_TTY" channel = "12" /> 
+                <irq type = "HARD" icuid = "29" isr = "ISR_TTY" channel = "13" /> 
+                <irq type = "HARD" icuid = "30" isr = "ISR_TTY" channel = "14" /> 
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc> 
+
+            <proc index = "1" >
+                <irq type = "PTI"  icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc index = "2" >
+                <irq type = "PTI"  icuid = "2" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc index  = "3" >
+                <irq type = "PTI"  icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" /> 
+            <periph type = "XICU" psegname = "PSEG_XICU" channels = "18" />
+            <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1" /> 
+            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "8" /> 
+            <periph type = "NIC"  psegname = "PSEG_NIC"  channels = "2" />
+            <periph type = "FBF"  psegname = "PSEG_FBF" />
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** segments used by the boot code / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_boot_code"      vbase = "0xBFC00000" mode = "CXW_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "boot_code"      type = "ELF" length = "0x00008000" binpath	= "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "ELF" length = "0x00001000" binpath	= "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00001000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00003000" />
+        </vseg>
+        <vseg name = "seg_boot_mapping"   vbase = "0x00004000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB" length  = "0x00004000" binpath	= "map.bin" />
+        </vseg>
+
+*** peripherals / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_fbf"            vbase = "0xB2000000" mode = "__W_" clusterid = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" clusterid = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" clusterid = "0" psegname = "PSEG_NIC" ident = "1" >
+            <vobj name = "nic"            type = "PERI" length  = "0x00021000" /> 
+        </vseg>
+
+*** segments used by the kernel / A[31:28] = 0x8 
+  
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"    type = "ELF" length = "0x00010000" binpath = "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"    type = "ELF" length = "0x00040000" binpath = "build/sys/sys.elf" />
+		</vseg>
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_uncdata" type = "ELF" length = "0x00010000" binpath = "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"    vbase = "0x80090000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name	= "kernel_init"   type = "ELF" length = "0x00010000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+
+        <vseg name = "seg_icu_0"          vbase = "0xE0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_XICU" > 
+            <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+
+        <vseg name = "seg_dma_0"          vbase = "0xD0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma_0"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+    </globalset> 
+
+    <vspaceset>
+        <vspace name = "router" startname = "router_data" > 
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "__WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "router_data" type	= "ELF" length = "0x00010000" binpath = "build/router/router.elf" />
+            </vseg>
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "router_code" type	= "ELF" length = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "ptab"        type	= "PTAB" length  = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_prod"  vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_prod"  type	= "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap_prod"   type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_cons"  vbase = "0x00030000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_cons"  type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_cons"   type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routA" vbase = "0x00050000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routA" type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routA"  type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routB" vbase = "0x00070000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routB" type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routB"  type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_mwmrs"       vbase = "0x00090000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "mwmr_in"     type = "MWMR" length = "0x00000020" init = "1" />
+                <vobj name = "mwmr_out"    type = "MWMR" length = "0x00000020" init = "1" />
+		    </vseg>
+
+            <task name = "producer" clusterid = "0" proclocid = "0" stackname = "stack_prod"  heapname = "heap_prod"  startid = "0" usetty = "1" />
+            <task name = "consumer" clusterid = "0" proclocid = "1" stackname = "stack_cons"  heapname = "heap_cons"  startid = "1" usetty = "1" />
+            <task name = "router_A" clusterid = "0" proclocid = "2" stackname = "stack_routA" heapname = "heap_routA" startid = "2" usetty = "1" />
+            <task name = "router_B" clusterid = "0" proclocid = "3" stackname = "stack_routB" heapname = "heap_routB" startid = "2" usetty = "1" />
+        </vspace>
+
+        <vspace name = "hello" startname = "hello_data" >
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "hello_data"  type	= "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "hello_code"  type	= "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" /> 
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	= "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_hello" clusterid = "0" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "pgcd" startname = "pgcd_data" >
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name	= "pgcd_data"  type	= "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "pgcd_code"   type = "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap"        type = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+
+            <task name = "main_pgcd" clusterid = "0" proclocid = "2" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "display" startname = "disp_data" >
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "disp_data"   type	= "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+			</vseg>
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "disp_code"   type	= "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length  = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	= "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_display" clusterid = "0" proclocid = "3" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" usedma = "1" />
+        </vspace>
+		
+
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/1c_4p_four.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/1c_4p_four.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/1c_4p_four.xml	(revision 283)
@@ -0,0 +1,246 @@
+<?xml version="1.0"?>
+
+<mapping_info   signature = "0xdeadbeef" 
+                name      = "1c_4p_four" 
+                cluster_x = "1" 
+                cluster_y = "1" 
+                vspaces   = "4" 
+                increment = "0x10000" >
+
+*** This section describes an instance of the "caba_vgsb_xicu_mmu" generic architecture
+*** containing 4 processors in one single cluster.
+
+    <clusterset>
+        <cluster index  = "0" >
+
+*** RAM, ROM and Peripherals used in the hardware architecture
+
+            <pseg name = "PSEG_RAM" type = "RAM"  base = "0x00000000" length = "0x00C00000" />
+            <pseg name = "PSEG_ROM" type = "ROM"  base = "0xBFC00000" length = "0x00010000" /> 
+            <pseg name = "PSEG_FBF" type = "PERI" base = "0x00D00000" length = "0x00200000" /> 
+            <pseg name = "PSEG_ICU" type = "PERI" base = "0x00F00000" length = "0x00001000" /> 
+            <pseg name = "PSEG_IOC" type = "PERI" base = "0x00F10000" length = "0x00001000" /> 
+            <pseg name = "PSEG_TTY" type = "PERI" base = "0x00F20000" length = "0x00001000" /> 
+            <pseg name = "PSEG_DMA" type = "PERI" base = "0x00F30000" length = "0x00008000" /> 
+            <pseg name = "PSEG_NIC" type = "PERI" base = "0x00F80000" length = "0x00021000" /> 
+             
+*** Peripherals unused in the hardware architecture 
+
+            <pseg name = "PSEG_GCD" type = "PERI" base = "0x00F50000" length = "0x00001000" /> 
+            <pseg name = "PSEG_COP" type = "PERI" base = "0x00F60000" length = "0x00001000" /> 
+            <pseg name = "PSEG_IOB" type = "PERI" base = "0x00FF0000" length = "0x00001000" /> 
+
+            <proc index = "0" >
+                <irq type = "PTI"  icuid = "0"  isr = "ISR_SWITCH" /> 
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DMA" channel = "0" /> 
+                <irq type = "HARD" icuid = "9"  isr = "ISR_DMA" channel = "1" /> 
+                <irq type = "HARD" icuid = "10" isr = "ISR_DMA" channel = "2" /> 
+                <irq type = "HARD" icuid = "11" isr = "ISR_DMA" channel = "3" /> 
+                <irq type = "HARD" icuid = "12" isr = "ISR_DMA" channel = "4" /> 
+                <irq type = "HARD" icuid = "13" isr = "ISR_DMA" channel = "5" /> 
+                <irq type = "HARD" icuid = "14" isr = "ISR_DMA" channel = "6" /> 
+                <irq type = "HARD" icuid = "15" isr = "ISR_DMA" channel = "7" /> 
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY" channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY" channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY" channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY" channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY" channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY" channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY" channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY" channel = "7" /> 
+                <irq type = "HARD" icuid = "24" isr = "ISR_TTY" channel = "8" /> 
+                <irq type = "HARD" icuid = "25" isr = "ISR_TTY" channel = "9" /> 
+                <irq type = "HARD" icuid = "26" isr = "ISR_TTY" channel = "10" /> 
+                <irq type = "HARD" icuid = "27" isr = "ISR_TTY" channel = "11" /> 
+                <irq type = "HARD" icuid = "28" isr = "ISR_TTY" channel = "12" /> 
+                <irq type = "HARD" icuid = "29" isr = "ISR_TTY" channel = "13" /> 
+                <irq type = "HARD" icuid = "30" isr = "ISR_TTY" channel = "14" /> 
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc>
+
+            <proc index = "1" >
+                <irq type = "PTI"  icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc index = "2" >
+                <irq type = "PTI"  icuid = "2" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc    index  = "3" >
+                <irq type = "PTI"  icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "IOC" psegname = "PSEG_IOC" channels  = "1" /> 
+            <periph type = "NIC" psegname = "PSEG_NIC" channels  = "8" /> 
+            <periph type = "TTY" psegname = "PSEG_TTY" channels  = "8" /> 
+            <periph type = "DMA" psegname = "PSEG_DMA" channels  = "1" /> 
+            <periph type = "XCU" psegname = "PSEG_ICU" channels  = "5" /> 
+            <periph type = "FBF" psegname = "PSEG_FBF" /> 
+
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Global vsegs used in the boot phase
+
+        <vseg name = "seg_boot_code"    vbase = "0xBFC00000" mode = "CXW_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "boot_code"    type = "ELF" length  = "0x00010000" binpath = "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_stack"   vbase = "0xBFC08000" mode = "C_W_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" > 
+            <vobj name = "boot_stack"   type = "BUFFER" length  = "0x00004000" />
+        </vseg>
+        <vseg name = "seg_boot_mapping" vbase = "0xBFC0c000" mode = "C_W_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" > 
+            <vobj name = "boot_mapping" type = "BLOB" length  = "0x00004000" binpath	= "map.bin" />
+        </vseg>
+
+*** Global vsegs used by the kernel
+
+        <vseg name = "seg_kernel_code"  vbase = "0x80000000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"  type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" /> 
+        </vseg>
+        <vseg name = "seg_kernel_data"  vbase = "0x80010000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"  type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" /> 
+        </vseg>
+        <vseg name = "seg_kernel_unc"   vbase = "0x80080000" mode = "__W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_unc"   type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" /> 
+        </vseg>
+        <vseg name = "seg_kernel_init"  vbase = "0x80090000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_init"  type = "ELF" length  = "0x00100000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+
+*** Frame buffer (up to 2 Mbytes)
+
+        <vseg name = "seg_fbf"          vbase = "0x00D00000" mode = "__W_" clusterid = "0" psegname = "PSEG_FBF" ident = "1" > 
+            <vobj name = "fbf"          type = "PERI" length  = "0x00200000" /> 
+        </vseg>
+
+*** Peripherals (4 Kbytes per peripheral / 4 Kbytes per channel for the DMA / 16 Kbytes per channel + 4Kbytes for NIC
+
+        <vseg name = "seg_icu"          vbase = "0x00F00000" mode = "__W_" clusterid = "0" psegname = "PSEG_ICU" ident = "1" > 
+            <vobj name = "icu"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"          vbase = "0x00F10000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOC" ident = "1" > 
+            <vobj name = "ioc"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"          vbase = "0x00F20000" mode = "__W_" clusterid = "0" psegname = "PSEG_TTY" ident = "1" > 
+            <vobj name = "tty"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_dma"          vbase = "0x00F30000" mode = "__W_" clusterid = "0" psegname = "PSEG_DMA" ident = "1" > 
+            <vobj name = "dma"          type = "PERI" length  = "0x00008000" /> 
+        </vseg>
+        <vseg name = "seg_gcd"          vbase = "0x00F50000" mode = "__W_" clusterid = "0" psegname = "PSEG_GCD" ident = "1" > 
+            <vobj name = "gcd"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_iob"          vbase = "0x00FF0000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOB" ident = "1" > 
+            <vobj name = "iob"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"          vbase = "0x00FA0000" mode = "__W_" clusterid = "0" psegname = "PSEG_NIC" ident = "1" > 
+            <vobj name = "nic"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+    </globalset> 
+
+    <vspaceset>
+
+        <vspace name = "router" startname = "data" >
+
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "__WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "data"     type = "ELF" length = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "code"     type = "ELF" length = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "ptab"     type = "PTAB" length = "0x00012000" align   = "13" /> 
+            </vseg>
+            <vseg name = "seg_stack_p"  vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "stack_p"  type = "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_p"   type = "BUFFER" length = "0x00010000" />
+			   </vseg>
+            <vseg name = "seg_stack_c"  vbase = "0x00030000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack_c"  type = "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_c"   type = "BUFFER" length = "0x00010000" />
+						</vseg>
+            <vseg name = "seg_stack_rA" vbase = "0x00050000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack_rA" type = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap_rA"  type = "BUFFER" length = "0x00010000" />
+            </vseg>
+            <vseg name = "seg_stack_rB" vbase = "0x00070000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack_rB" type = "BUFFER" length  = "0x00010000" /> 
+                <vobj name = "heap_rB"  type = "BUFFER" length = "0x00010000" />
+            </vseg>
+            <vseg name = "seg_mwmrs"    vbase = "0x00090000" mode = "__WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "mwmr_in"  type = "MWMR" length = "0x00000020" init = "1" />
+                <vobj name = "mwmr_out" type = "MWMR" length = "0x00000020" init = "1" />
+            </vseg>
+
+            <task name = "producer" clusterid = "0" proclocid = "0" stackname = "stack_p"  heapname = "heap_p"  startid = "0" usetty = "1" />
+            <task name = "consumer" clusterid = "0" proclocid = "1" stackname = "stack_c"  heapname = "heap_c"  startid = "1" usetty = "1" />
+            <task name = "router_A" clusterid = "0" proclocid = "2" stackname = "stack_rA" heapname = "heap_rA" startid = "2" usetty = "1" />
+            <task name = "router_B" clusterid = "0" proclocid = "3" stackname = "stack_rB" heapname = "heap_rB" startid = "2" usetty = "1" />
+
+        </vspace>
+
+        <vspace name = "hello" startname = "data" >
+
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "stack"    type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+
+*** allocate NIC channel 2 => base = 0x00F80000 / offset = 0x8000 
+
+            <vseg name = "seg_nic_2"    vbase = "0x00F88000" mode = "__WU" clusterid = "0" psegname  = "PSEG_NIC" ident = "1" >
+                <vobj name = "nic_2"    type = "BUFFER" length  = "0x00004000" />
+            </vseg>
+
+            <task name = "main" clusterid = "0" proclocid = "2" stackname = "stack" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "pgcd" startname = "data" >
+
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "stack"    type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+
+            <task name = "main" clusterid = "0" proclocid = "3" stackname = "stack" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "display" startname = "data" >
+
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "stack"    type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+
+            <task name = "main" clusterid = "0" proclocid = "3" stackname = "stack" startid = "0" usetty = "1" usefbdma = "1" />
+        </vspace>
+
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/1c_4p_four_dhrystone.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/1c_4p_four_dhrystone.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/1c_4p_four_dhrystone.xml	(revision 283)
@@ -0,0 +1,207 @@
+<?xml version="1.0"?>
+
+<mapping_info   signature = "0xdeadbeef" 
+                name      = "1c_4p_four_dhrystone" 
+                cluster_x = "1" 
+                cluster_y = "1" 
+                vspaces   = "4" 
+                increment = "0x10000" >
+
+    <clusterset>
+        <cluster index  = "0" >
+
+*** RAM, ROM and Peripherals used in the hardware architecture
+
+            <pseg name = "PSEG_RAM"  type  = "RAM"  base = "0x0000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type  = "PERI" base = "0x00B0000000" length = "0x0000001000" />
+            <pseg name = "PSEG_DMA"  type  = "PERI" base = "0x00B1000000" length = "0x0000001000" />
+            <pseg name = "PSEG_FBF"  type  = "PERI" base = "0x00B2000000" length = "0x0000200000" />
+            <pseg name = "PSEG_IOC"  type  = "PERI" base = "0x00B3000000" length = "0x0000001000" />
+            <pseg name = "PSEG_TTY"  type  = "PERI" base = "0x00B4000000" length = "0x0000001000" />
+            <pseg name = "PSEG_NIC"  type  = "PERI" base = "0x00B5000000" length = "0x0000021000" />
+            <pseg name = "PSEG_ROM"  type  = "ROM"  base = "0x00BFC00000" length = "0x0000100000" />
+
+            <proc index = "0" >
+                <irq type = "PTI"  icuid = "0"  isr = "ISR_SWITCH" />
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DMA" channel = "0" />
+                <irq type = "HARD" icuid = "9"  isr = "ISR_DMA" channel = "1" />
+                <irq type = "HARD" icuid = "10" isr = "ISR_DMA" channel = "2" />
+                <irq type = "HARD" icuid = "11" isr = "ISR_DMA" channel = "3" />
+                <irq type = "HARD" icuid = "12" isr = "ISR_DMA" channel = "4" />
+                <irq type = "HARD" icuid = "13" isr = "ISR_DMA" channel = "5" />
+                <irq type = "HARD" icuid = "14" isr = "ISR_DMA" channel = "6" />
+                <irq type = "HARD" icuid = "15" isr = "ISR_DMA" channel = "7" />
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY" channel = "0" />
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY" channel = "1" />
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY" channel = "2" />
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY" channel = "3" />
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY" channel = "4" />
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY" channel = "5" />
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY" channel = "6" />
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY" channel = "7" />
+                <irq type = "HARD" icuid = "24" isr = "ISR_TTY" channel = "8" />
+                <irq type = "HARD" icuid = "25" isr = "ISR_TTY" channel = "9" />
+                <irq type = "HARD" icuid = "26" isr = "ISR_TTY" channel = "10" />
+                <irq type = "HARD" icuid = "27" isr = "ISR_TTY" channel = "11" />
+                <irq type = "HARD" icuid = "28" isr = "ISR_TTY" channel = "12" />
+                <irq type = "HARD" icuid = "29" isr = "ISR_TTY" channel = "13" />
+                <irq type = "HARD" icuid = "30" isr = "ISR_TTY" channel = "14" />
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" />
+            </proc>
+
+            <proc index = "1" >
+                <irq type = "PTI" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc index = "2" >
+                <irq type = "PTI" icuid = "2" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc    index  = "3" >
+                <irq type = "PTI" icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "IOC" psegname = "PSEG_IOC" channels  = "1" />
+            <periph type = "NIC" psegname = "PSEG_NIC" channels  = "8" />
+            <periph type = "TTY" psegname = "PSEG_TTY" channels  = "8" />
+            <periph type = "DMA" psegname = "PSEG_DMA" channels  = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels  = "5" />
+            <periph type = "FBF" psegname = "PSEG_FBF" />
+
+        </cluster>
+    </clusterset>
+
+    <globalset>
+
+*** Global vsegs used in the boot phase
+
+        <vseg name = "seg_boot_code"    vbase = "0xBFC00000" mode = "CXW_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "boot_code"    type = "ELF" length  = "0x00008000" binpath = "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_mapping" vbase = "0xBFC08000" mode = "C_W_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "boot_mapping" type = "BLOB" length  = "0x00004000" binpath	= "map.bin" />
+        </vseg>
+        <vseg name = "seg_boot_stack"   vbase = "0x00000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"   type = "BUFFER" length  = "0x00004000" />
+        </vseg>
+
+*** Global vsegs used by the kernel
+
+        <vseg name = "seg_kernel_code"  vbase = "0x80000000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "kernel_code"  type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"  vbase = "0x80020000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "kernel_data"  type = "ELF" length  = "0x00040000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_uncdata"   vbase = "0x80080000" mode = "__W_" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "kernel_uncdata"   type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"  vbase = "0x80090000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "kernel_init"  type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+
+*** Frame buffer (up to 2 Mbytes)
+
+        <vseg name = "seg_fbf"            vbase = "0xB2000000" mode = "__W_" clusterid = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" />
+        </vseg>
+
+*** XICU / A[31:28] = 0xE
+        <vseg name = "seg_icu"          vbase = "0xE0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_XCU"  >
+            <vobj name = "icu"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** ioc
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** tty
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" clusterid = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** DMA / A[31:28] = 0xD
+        <vseg name = "seg_dma"          vbase = "0xD0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** Replicated schedulers / A[31:28] = 0xF
+        <vseg name = "seg_sched"        vbase = "0xF0000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched"      type = "SCHED" length  = "0x00004000" />
+        </vseg>
+
+    </globalset>
+
+    <vspaceset>
+
+        <vspace name = "dhrystone_0" startname = "data" >
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/dhrystone/dhrystone.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/dhrystone/dhrystone.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_heap"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack" type = "BUFFER" length  = "0x00010000" />
+                <vobj name = "heap"  type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+            <task name = "main" clusterid = "0" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "dhrystone_1" startname = "data" >
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/dhrystone/dhrystone.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/dhrystone/dhrystone.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_heap"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack" type = "BUFFER" length  = "0x00010000" />
+                <vobj name = "heap"  type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+            <task name = "main" clusterid = "0" proclocid = "1" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "dhrystone_2" startname = "data" >
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/dhrystone/dhrystone.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/dhrystone/dhrystone.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_heap"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack" type = "BUFFER" length  = "0x00010000" />
+                <vobj name = "heap"  type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+            <task name = "main" clusterid = "0" proclocid = "2" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "dhrystone_3" startname = "data" >
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/dhrystone/dhrystone.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/dhrystone/dhrystone.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_heap"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack" type = "BUFFER" length  = "0x00010000" />
+                <vobj name = "heap"  type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+            <task name = "main" clusterid = "0" proclocid = "3" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/1c_4p_four_tsar_generic_mmu.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/1c_4p_four_tsar_generic_mmu.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/1c_4p_four_tsar_generic_mmu.xml	(revision 283)
@@ -0,0 +1,234 @@
+<?xml version="1.0"?>
+
+<mapping_info   signature = "0xdeadbeef" name = "1c_4p_four" cluster_x = "1" cluster_y = "1" vspaces  = "4" >
+
+    <clusterset>
+        <cluster index  = "0" >
+
+*** RAM, ROM and Peripherals used in the hardware architecture
+
+            <pseg name = "PSEG_RAM" type = "RAM"  base = "0x00000000" length = "0x00C00000" />
+            <pseg name = "PSEG_ROM" type = "ROM"  base = "0xBFC00000" length = "0x00100000" /> 
+            <pseg name = "PSEG_FBF" type = "PERI" base = "0xBFD00000" length = "0x00200000" /> 
+            <pseg name = "PSEG_ICU" type = "PERI" base = "0x00F00000" length = "0x00001000" /> 
+            <pseg name = "PSEG_IOC" type = "PERI" base = "0xBFF10000" length = "0x00001000" /> 
+            <pseg name = "PSEG_TTY" type = "PERI" base = "0xBFF20000" length = "0x00001000" /> 
+            <pseg name = "PSEG_DMA" type = "PERI" base = "0x00F30000" length = "0x00001000" /> 
+            <pseg name = "PSEG_NIC" type = "PERI" base = "0xBFF80000" length = "0x00021000" /> 
+             
+*** Peripherals unused in the hardware architecture 
+
+            <pseg name = "PSEG_GCD" type = "PERI" base = "0x00F50000" length = "0x00001000" /> 
+            <pseg name = "PSEG_COP" type = "PERI" base = "0x00F60000" length = "0x00001000" /> 
+            <pseg name = "PSEG_IOB" type = "PERI" base = "0x00FF0000" length = "0x00001000" /> 
+
+            <proc index = "0" >
+                <irq type = "PTI"  icuid = "0"  isr = "ISR_SWITCH" /> 
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DMA" channel = "0" /> 
+                <irq type = "HARD" icuid = "9"  isr = "ISR_DMA" channel = "1" /> 
+                <irq type = "HARD" icuid = "10" isr = "ISR_DMA" channel = "2" /> 
+                <irq type = "HARD" icuid = "11" isr = "ISR_DMA" channel = "3" /> 
+                <irq type = "HARD" icuid = "12" isr = "ISR_DMA" channel = "4" /> 
+                <irq type = "HARD" icuid = "13" isr = "ISR_DMA" channel = "5" /> 
+                <irq type = "HARD" icuid = "14" isr = "ISR_DMA" channel = "6" /> 
+                <irq type = "HARD" icuid = "15" isr = "ISR_DMA" channel = "7" /> 
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY" channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY" channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY" channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY" channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY" channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY" channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY" channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY" channel = "7" /> 
+                <irq type = "HARD" icuid = "24" isr = "ISR_TTY" channel = "8" /> 
+                <irq type = "HARD" icuid = "25" isr = "ISR_TTY" channel = "9" /> 
+                <irq type = "HARD" icuid = "26" isr = "ISR_TTY" channel = "10" /> 
+                <irq type = "HARD" icuid = "27" isr = "ISR_TTY" channel = "11" /> 
+                <irq type = "HARD" icuid = "28" isr = "ISR_TTY" channel = "12" /> 
+                <irq type = "HARD" icuid = "29" isr = "ISR_TTY" channel = "13" /> 
+                <irq type = "HARD" icuid = "30" isr = "ISR_TTY" channel = "14" /> 
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc>
+
+            <proc index = "1" >
+                <irq type = "PTI" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc index = "2" >
+                <irq type = "PTI" icuid = "2" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc    index  = "3" >
+                <irq type = "PTI" icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "IOC" psegname = "PSEG_IOC" channels  = "1" /> 
+            <periph type = "NIC" psegname = "PSEG_NIC" channels  = "8" /> 
+            <periph type = "TTY" psegname = "PSEG_TTY" channels  = "8" /> 
+            <periph type = "DMA" psegname = "PSEG_DMA" channels  = "1" /> 
+            <periph type = "XICU" psegname = "PSEG_ICU" channels  = "5" /> 
+            <periph type = "FBF" psegname = "PSEG_FBF" /> 
+
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Global vsegs used in the boot phase
+
+        <vseg name = "seg_boot_code"    vbase = "0xBFC00000" mode = "CXW_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "boot_code"    type = "ELF" length  = "0x00010000" binpath = "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_stack"   vbase = "0xBFC08000" mode = "C_W_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" > 
+            <vobj name = "boot_stack"   type = "BUFFER" length  = "0x00004000" />
+        </vseg>
+        <vseg name = "seg_boot_mapping" vbase = "0xBFC0c000" mode = "C_W_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" > 
+            <vobj name = "boot_mapping" type = "BLOB" length  = "0x00004000" binpath	= "map.bin" />
+        </vseg>
+
+*** Global vsegs used by the kernel
+
+        <vseg name = "seg_kernel_code"  vbase = "0x80000000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"  type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" /> 
+        </vseg>
+        <vseg name = "seg_kernel_data"  vbase = "0x80010000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"  type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" /> 
+        </vseg>
+        <vseg name = "seg_kernel_unc"   vbase = "0x80080000" mode = "__W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_unc"   type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" /> 
+        </vseg>
+        <vseg name = "seg_kernel_init"  vbase = "0x80090000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_init"  type = "ELF" length  = "0x00100000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+
+*** Frame buffer (up to 2 Mbytes)
+
+        <vseg name = "seg_fbf"          vbase = "0xBFD00000" mode = "__W_" clusterid = "0" psegname = "PSEG_FBF" ident = "1" > 
+            <vobj name = "fbf"          type = "PERI" length  = "0x00200000" /> 
+        </vseg>
+
+*** Peripherals (4 Kbytes per peripheral / 4 Kbytes per channel for the DMA / 16 Kbytes per channel + 4Kbytes for NIC
+
+        <vseg name = "seg_icu"          vbase = "0x00F00000" mode = "__W_" clusterid = "0" psegname = "PSEG_ICU" ident = "1" > 
+            <vobj name = "icu"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"          vbase = "0xBFF10000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOC" ident = "1" > 
+            <vobj name = "ioc"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"          vbase = "0xBFF20000" mode = "__W_" clusterid = "0" psegname = "PSEG_TTY" ident = "1" > 
+            <vobj name = "tty"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_dma"          vbase = "0x00F30000" mode = "__W_" clusterid = "0" psegname = "PSEG_DMA" ident = "1" > 
+            <vobj name = "dma"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_gcd"          vbase = "0x00F50000" mode = "__W_" clusterid = "0" psegname = "PSEG_GCD" ident = "1" > 
+            <vobj name = "gcd"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_iob"          vbase = "0x00FF0000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOB" ident = "1" > 
+            <vobj name = "iob"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"          vbase = "0xBFFA0000" mode = "__W_" clusterid = "0" psegname = "PSEG_NIC" ident = "1" > 
+            <vobj name = "nic"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+    </globalset> 
+
+    <vspaceset>
+
+        <vspace name = "router" startname = "data" >
+
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "__WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "data"     type = "ELF" length  = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "code"     type = "ELF" length  = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "ptab"     type = "PTAB" length  = "0x00012000" align   = "13" /> 
+            </vseg>
+            <vseg name = "seg_stack_p"  vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "stack_p"  type = "BUFFER" length  = "0x00010000" />
+			   </vseg>
+            <vseg name = "seg_stack_c"  vbase = "0x00020000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack_c"  type = "BUFFER" length  = "0x00010000" />
+						</vseg>
+            <vseg name = "seg_stack_rA" vbase = "0x00030000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack_rA" type = "BUFFER" length  = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_rB" vbase = "0x00040000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "stack_rB" type = "BUFFER" length  = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_mwmrs"    vbase = "0x00050000" mode = "__WU" clusterid = "0" psegname  = "PSEG_RAM" >
+                <vobj name = "mwmr_in"  type = "MWMR" length  = "0x00000020" init = "1" />
+                <vobj name = "mwmr_out" type = "MWMR" length  = "0x00000020" init = "1" />
+            </vseg>
+
+            <task name = "producer" clusterid = "0" proclocid = "1" stackname = "stack_p"  startid = "0" usetty = "1" />
+            <task name = "consumer" clusterid = "0" proclocid = "1" stackname = "stack_c"  startid = "1" usetty = "1" />
+            <task name = "router_A" clusterid = "0" proclocid = "2" stackname = "stack_rA" startid = "2" usetty = "1" />
+            <task name = "router_B" clusterid = "0" proclocid = "3" stackname = "stack_rB" startid = "2" usetty = "1" />
+
+        </vspace>
+
+        <vspace name = "hello" startname = "data" >
+
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "stack"    type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+
+*** allocate NIC channel 2 => base = 0x00F80000 / offset = 0x8000 
+
+            <vseg name = "seg_nic_2"    vbase = "0xBFF88000" mode = "__WU" clusterid = "0" psegname  = "PSEG_NIC" ident = "1" >
+                <vobj name = "nic_2"    type = "BUFFER" length  = "0x00004000" />
+            </vseg>
+
+            <task name = "main" clusterid = "0" proclocid = "2" stackname = "stack" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "pgcd" startname = "data" >
+
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "stack"    type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+
+            <task name = "main" clusterid = "0" proclocid = "3" stackname = "stack" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "display" startname = "data" >
+
+            <vseg name = "seg_data"     vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "data"     type = "ELF" length    = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_code"     vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "code"     type = "ELF" length    = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"     vbase = "0x00300000" mode = "C___" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "ptab"     type = "PTAB" length   = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"    vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname  = "PSEG_RAM" > 
+                <vobj name = "stack"    type = "BUFFER" length  = "0x00010000" />
+            </vseg>
+
+            <task name = "main" clusterid = "0" proclocid = "0" stackname = "stack" startid = "0" usetty = "1" usefbdma = "1" />
+        </vspace>
+
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/1c_4p_gameoflife.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/1c_4p_gameoflife.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/1c_4p_gameoflife.xml	(revision 283)
@@ -0,0 +1,181 @@
+<?xml version="1.0"?>
+
+<mapping_info   signature = "0xdeadbeef" 
+                name      = "1c_4p_gameoflife" 
+                cluster_x = "1" 
+                cluster_y = "1" 
+                vspaces   = "1"
+                increment = "0x10000 >
+
+    <clusterset>
+        <cluster index  = "0" >
+
+*** RAM, ROM and Peripherals used in the hardware architecture
+
+            <pseg name = "PSEG_RAM"  type  = "RAM"  base = "0x0000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type  = "PERI" base = "0x00B0000000" length = "0x0000001000" />
+            <pseg name = "PSEG_DMA"  type  = "PERI" base = "0x00B1000000" length = "0x0000001000" />
+            <pseg name = "PSEG_FBF"  type  = "PERI" base = "0x00B2000000" length = "0x0000200000" />
+            <pseg name = "PSEG_IOC"  type  = "PERI" base = "0x00B3000000" length = "0x0000001000" />
+            <pseg name = "PSEG_TTY"  type  = "PERI" base = "0x00B4000000" length = "0x0000001000" />
+            <pseg name = "PSEG_NIC"  type  = "PERI" base = "0x00B5000000" length = "0x0000021000" />
+            <pseg name = "PSEG_ROM"  type  = "ROM"  base = "0x00BFC00000" length = "0x0000100000" />
+             
+*** Peripherals unused in the hardware architecture 
+
+
+            <proc index = "0" >
+                <irq type = "PTI"  icuid = "0"  isr = "ISR_SWITCH" /> 
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DMA" channel = "0" /> 
+                <irq type = "HARD" icuid = "9"  isr = "ISR_DMA" channel = "1" /> 
+                <irq type = "HARD" icuid = "10" isr = "ISR_DMA" channel = "2" /> 
+                <irq type = "HARD" icuid = "11" isr = "ISR_DMA" channel = "3" /> 
+                <irq type = "HARD" icuid = "12" isr = "ISR_DMA" channel = "4" /> 
+                <irq type = "HARD" icuid = "13" isr = "ISR_DMA" channel = "5" /> 
+                <irq type = "HARD" icuid = "14" isr = "ISR_DMA" channel = "6" /> 
+                <irq type = "HARD" icuid = "15" isr = "ISR_DMA" channel = "7" /> 
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY" channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY" channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY" channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY" channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY" channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY" channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY" channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY" channel = "7" /> 
+                <irq type = "HARD" icuid = "24" isr = "ISR_TTY" channel = "8" /> 
+                <irq type = "HARD" icuid = "25" isr = "ISR_TTY" channel = "9" /> 
+                <irq type = "HARD" icuid = "26" isr = "ISR_TTY" channel = "10" /> 
+                <irq type = "HARD" icuid = "27" isr = "ISR_TTY" channel = "11" /> 
+                <irq type = "HARD" icuid = "28" isr = "ISR_TTY" channel = "12" /> 
+                <irq type = "HARD" icuid = "29" isr = "ISR_TTY" channel = "13" /> 
+                <irq type = "HARD" icuid = "30" isr = "ISR_TTY" channel = "14" /> 
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc>
+
+            <proc index = "1" >
+                <irq type = "PTI" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc index = "2" >
+                <irq type = "PTI" icuid = "2" isr = "ISR_SWITCH" />
+            </proc>
+
+            <proc    index  = "3" >
+                <irq type = "PTI" icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "IOC" psegname = "PSEG_IOC" channels  = "1" /> 
+            <periph type = "NIC" psegname = "PSEG_NIC" channels  = "8" /> 
+            <periph type = "TTY" psegname = "PSEG_TTY" channels  = "2" /> 
+            <periph type = "DMA" psegname = "PSEG_DMA" channels  = "1" /> 
+            <periph type = "XCU" psegname = "PSEG_XCU" channels  = "5" /> 
+            <periph type = "FBF" psegname = "PSEG_FBF" /> 
+
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Global vsegs used in the boot phase
+
+
+        <vseg name = "seg_boot_code"      vbase = "0xBFC00000" mode = "CXW_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "boot_code"      type = "ELF" length = "0x00008000" binpath	= "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "ELF" length = "0x00001000" binpath	= "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00001000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00003000" />
+        </vseg>
+        <vseg name = "seg_boot_mapping"   vbase = "0x00004000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB" length  = "0x00004000" binpath	= "map.bin" />
+        </vseg>
+
+*** Global vsegs used by the kernel
+
+        <vseg name = "seg_kernel_code"  vbase = "0x80000000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "kernel_code"  type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"  vbase = "0x80020000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "kernel_data"  type = "ELF" length  = "0x00040000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_uncdata"   vbase = "0x80080000" mode = "__W_" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "kernel_uncdata"   type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"  vbase = "0x80090000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "kernel_init"  type = "ELF" length  = "0x00010000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+
+*** Frame buffer (up to 2 Mbytes)
+
+        <vseg name = "seg_fbf"            vbase = "0xB2000000" mode = "__W_" clusterid = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" />
+        </vseg>
+
+*** XCU / A[31:28] = 0xE
+        <vseg name = "seg_icu"          vbase = "0xE0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_XCU"  >
+            <vobj name = "icu"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** ioc
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** tty
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" clusterid = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** DMA / A[31:28] = 0xD
+        <vseg name = "seg_dma"          vbase = "0xD0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma"          type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** Replicated schedulers / A[31:28] = 0xF
+        <vseg name = "seg_sched"        vbase = "0xF0000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched"      type = "SCHED" length  = "0x00004000" />
+        </vseg>
+
+    </globalset> 
+
+    <vspaceset>
+
+        <vspace name = "gameoflife" startname = "data" >
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "data"        type	= "ELF" length = "0x00010000" binpath = "build/gameoflife/gameoflife.elf" />
+            </vseg>
+			
+	    <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" />
+            </vseg>
+			
+	    <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "code"        type = "ELF" length = "0x00010000" binpath = "build/gameoflife/gameoflife.elf" />
+            </vseg>
+			
+	    <vseg name = "seg_stack_0"     vbase = "0x00020000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_0"     type = "BUFFER" length = "0x00008000" /> 
+            </vseg>
+
+            <vseg name = "seg_stack_1"     vbase = "0x00030000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_1"     type = "BUFFER" length = "0x00008000" /> 
+            </vseg>
+            
+            <vseg name = "seg_stack_2"     vbase = "0x00040000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_2"     type = "BUFFER" length = "0x00008000" /> 
+            </vseg>
+            
+            <vseg name = "seg_stack_3"     vbase = "0x00050000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_3"     type = "BUFFER" length = "0x00008000" /> 
+            </vseg>
+          
+            <task name = "main_gameoflife_0" clusterid = "0" proclocid = "0" stackname = "stack_0" startid = "0" usetty = "1" />
+            <task name = "main_gameoflife_1" clusterid = "0" proclocid = "1" stackname = "stack_1" startid = "0" usetty = "0" />
+            <task name = "main_gameoflife_2" clusterid = "0" proclocid = "2" stackname = "stack_2" startid = "0" usetty = "0" />
+            <task name = "main_gameoflife_3" clusterid = "0" proclocid = "3" stackname = "stack_3" startid = "0" usetty = "0" />
+
+        </vspace>
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/4c_1p_40.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/4c_1p_40.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/4c_1p_40.xml	(revision 283)
@@ -0,0 +1,288 @@
+<?xml version="1.0"?>
+
+<mapping_info signature    = "0xdeadbeef" 
+              name         = "4c_1p_40" 
+              cluster_x    = "2" 
+              cluster_y    = "2" 
+              vspaces      = "4"
+              increment    = "0x0010000" >
+
+*** This first section describes an instance of the "tsar_generic_xbar" architecture
+*** with 4 clusters, 1 processor per cluster and 40 bits physical address.
+
+    <clusterset>
+
+        <cluster index = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x00B1000000" length = "0x0000008000" />
+
+*** Boot ROM and non replicated peripherals
+
+            <pseg name = "PSEG_FBF"  type = "PERI" base = "0x00B2000000" length = "0x0000004000" /> 
+            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00B3000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00B4000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_NIC"  type = "PERI" base = "0x00B5000000" length = "0x0000021000" />
+            <pseg name = "PSEG_CMA"  type = "PERI" base = "0x00B6000000" length = "0x0000004000" />
+            <pseg name = "PSEG_IOB"  type = "PERI" base = "0x00BE000000" length = "0x0000100000" />
+            <pseg name = "PSEG_ROM"  type = "ROM"  base = "0x00BFC00000" length = "0x0000100000" />
+
+            <proc index  = "0" >
+                <irq type = "HARD" icuid = "0"  isr = "ISR_SWITCH" /> 
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DMA" channel = "0" /> 
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY" channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY" channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY" channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY" channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY" channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY" channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY" channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY" channel = "7" /> 
+                <irq type = "HARD" icuid = "24" isr = "ISR_TTY" channel = "8" /> 
+                <irq type = "HARD" icuid = "25" isr = "ISR_TTY" channel = "9" />
+                <irq type = "HARD" icuid = "26" isr = "ISR_TTY" channel = "10" /> 
+                <irq type = "HARD" icuid = "27" isr = "ISR_TTY" channel = "11" /> 
+                <irq type = "HARD" icuid = "28" isr = "ISR_TTY" channel = "12" /> 
+                <irq type = "HARD" icuid = "29" isr = "ISR_TTY" channel = "13" /> 
+                <irq type = "HARD" icuid = "30" isr = "ISR_TTY" channel = "14" /> 
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" channel = "0" /> 
+            </proc> 
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" /> 
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1" /> 
+            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "8" /> 
+            <periph type = "NIC"  psegname = "PSEG_NIC"  channels = "2" />
+            <periph type = "FBF"  psegname = "PSEG_FBF" />
+        </cluster>
+
+        <cluster index = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x4000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x40B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x40B1000000" length = "0x0000008000" />
+
+            <proc index = "0" >
+                <irq type = "HARD" icuid = "0"  isr = "ISR_SWITCH" />
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DMA" channel = "0" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "2" />
+        </cluster>
+
+        <cluster index = "2" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x8000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x80B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x80B1000000" length = "0x0000008000" />
+
+            <proc index = "0" >
+                <irq type = "HARD" icuid = "0" isr = "ISR_SWITCH" />
+                <irq type = "HARD" icuid = "8" isr = "ISR_DMA" channel = "0" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "2" />
+        </cluster>
+
+        <cluster index = "3" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0xC000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0xC0B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0xC0B1000000" length = "0x0000008000" />
+
+            <proc index = "0" >
+                <irq type = "HARD" icuid = "0" isr = "ISR_SWITCH" />
+                <irq type = "HARD" icuid = "8" isr = "ISR_DMA" channel = "0" />
+            </proc>
+
+            <periph  type = "DMA" psegname = "PSEG_DMA"  channels = "4" />
+            <periph  type = "XCU" psegname = "PSEG_XCU"  channels = "2" />
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** segments used by the boot code / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_boot_code"      vbase = "0xBFC00000" mode = "CXW_" clusterid = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "boot_code"      type = "ELF" length = "0x00008000" binpath	= "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "ELF" length = "0x00001000" binpath	= "build/boot/boot.elf" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00001000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00003000" />
+        </vseg>
+        <vseg name = "seg_boot_mapping"   vbase = "0x00004000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB" length  = "0x00004000" binpath	= "map.bin" />
+        </vseg>
+
+*** Non replicated peripherals / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_fbf"            vbase = "0xB2000000" mode = "__W_" clusterid = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" clusterid = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" clusterid = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" clusterid = "0" psegname = "PSEG_NIC" ident = "1" >
+            <vobj name = "nic"            type = "PERI" length  = "0x00021000" /> 
+        </vseg>
+
+*** segments used by the kernel / A[31:28] = 0x8 
+  
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"    type = "ELF" length = "0x00010000" binpath = "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"    type = "ELF" length = "0x00040000" binpath = "build/sys/sys.elf" />
+		</vseg>
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_uncdata" type = "ELF" length = "0x00010000" binpath = "build/sys/sys.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"    vbase = "0x80090000" mode = "CX__" clusterid = "0" psegname = "PSEG_RAM" > 
+            <vobj name	= "kernel_init"   type = "ELF" length = "0x00010000" binpath	= "build/sys/sys.elf" />
+        </vseg>
+
+*** Replicated ICUS / A[31:28] = 0xE / Increment = 0x10000             
+
+        <vseg name = "seg_icu_0"          vbase = "0xE0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_XCU"  > 
+            <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_1"          vbase = "0xE0010000" mode = "__W_" clusterid = "1" psegname = "PSEG_XCU"  > 
+            <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_2"          vbase = "0xE0020000" mode = "__W_" clusterid = "2" psegname = "PSEG_XCU"  > 
+            <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_3"          vbase = "0xE0030000" mode = "__W_" clusterid = "3" psegname = "PSEG_XCU"  > 
+            <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+
+*** Replicated DMAs / A[31:28] = 0xD / Increment = 0x10000
+
+        <vseg name = "seg_dma_0"          vbase = "0xD0000000" mode = "__W_" clusterid = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma_0"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_1"          vbase = "0xD0010000" mode = "__W_" clusterid = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_1"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_2"          vbase = "0xD0020000" mode = "__W_" clusterid = "2" psegname = "PSEG_DMA" >
+            <vobj name = "dma_2"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_3"          vbase = "0xD0030000" mode = "__W_" clusterid = "3" psegname = "PSEG_DMA" >
+            <vobj name = "dma_3"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+
+*** Replicated schedulers / A[31:28] = 0xF / Increment = 0x10000
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" clusterid = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" clusterid = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_1"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_2"        vbase = "0xF0020000" mode = "C_W_" clusterid = "2" psegname = "PSEG_RAM" >
+            <vobj name = "sched_2"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_3"        vbase = "0xF0030000" mode = "C_W_" clusterid = "3" psegname = "PSEG_RAM" >
+            <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+***
+    </globalset> 
+
+    <vspaceset>
+        <vspace name = "router" startname = "router_data" > 
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "__WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "router_data" type	= "ELF" length = "0x00010000" binpath = "build/router/router.elf" />
+            </vseg>
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "router_code" type	= "ELF" length = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "ptab"        type	= "PTAB" length  = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_prod"  vbase = "0x00010000" mode = "C_WU" clusterid = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_prod"  type	= "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap_prod"   type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_cons"  vbase = "0x00030000" mode = "C_WU" clusterid = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_cons"  type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_cons"   type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routA" vbase = "0x00050000" mode = "C_WU" clusterid = "2" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routA" type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routA"  type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routB" vbase = "0x00070000" mode = "C_WU" clusterid = "3" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routB" type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routB"  type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_mwmrs"       vbase = "0x00090000" mode = "__WU" clusterid = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "mwmr_in"     type = "MWMR" length = "0x00000020" init = "1" />
+                <vobj name = "mwmr_out"    type = "MWMR" length = "0x00000020" init = "1" />
+		    </vseg>
+
+            <task name = "producer" clusterid = "0" proclocid = "0" stackname = "stack_prod"  heapname = "heap_prod"  startid = "0" usetty = "1" />
+            <task name = "consumer" clusterid = "1" proclocid = "0" stackname = "stack_cons"  heapname = "heap_cons"  startid = "1" usetty = "1" />
+            <task name = "router_A" clusterid = "2" proclocid = "0" stackname = "stack_routA" heapname = "heap_routA" startid = "2" usetty = "1" />
+            <task name = "router_B" clusterid = "3" proclocid = "0" stackname = "stack_routB" heapname = "heap_routB" startid = "2" usetty = "1" />
+        </vspace>
+
+        <vspace name = "hello" startname = "hello_data" >
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "C_WU" clusterid = "1" psegname = "PSEG_RAM" >
+                <vobj name = "hello_data"  type	= "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "hello_code"  type	= "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "1" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" /> 
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00010000" mode = "C_WU" clusterid = "1" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	= "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_hello" clusterid = "1" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "pgcd" startname = "pgcd_data" >
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "C_WU" clusterid = "2" psegname = "PSEG_RAM" >
+                <vobj name	= "pgcd_data"  type	= "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "2" psegname = "PSEG_RAM" >
+                <vobj name = "pgcd_code"   type = "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "2" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00010000" mode = "C_WU" clusterid = "2" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap"        type = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+
+            <task name = "main_pgcd" clusterid = "2" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "display" startname = "disp_data" >
+            <vseg name = "seg_data"        vbase = "0x00800000" mode = "C_WU" clusterid = "3" psegname = "PSEG_RAM" >
+                <vobj name = "disp_data"   type	= "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+			</vseg>
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" clusterid = "3" psegname = "PSEG_RAM" >
+                <vobj name = "disp_code"   type	= "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00300000" mode = "C___" clusterid = "3" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length  = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00010000" mode = "C_WU" clusterid = "3" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	= "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_display" clusterid = "3" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" usedma = "1" />
+        </vspace>
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/4c_1p_four.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/4c_1p_four.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/4c_1p_four.xml	(revision 283)
@@ -0,0 +1,340 @@
+<?xml version="1.0"?>
+
+<mapping_info signature    = "0xdeadbeef" 
+              name         = "4c_1p_four" 
+              x_size       = "2" 
+              y_size       = "2" 
+              x_width      = "4"
+              y_width      = "4"
+              vspaces      = "4"
+              increment    = "0x10000" >
+
+*** The "increment" parameter is the virtual address cluster increment 
+*** The physical address cluster increment is 0x10000000000 / NB_CLUSTERS
+
+*** This first section describes an instance of the "tsar_generic_xbar" architecture
+*** with 4 clusters, 1 processor per cluster and 40 bits physical address.
+
+    <clusterset>
+
+        <cluster x = "0" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x00B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x00B8000000" length = "0x0000001000" />
+
+*** Non replicated peripherals (including the ROM containing the preloader code)
+
+            <pseg name = "PSEG_FBF"  type = "PERI" base = "0x00B2000000" length = "0x0000004000" /> 
+            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00B3000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00B4000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_NIC"  type = "PERI" base = "0x00B5000000" length = "0x0000080000" />
+            <pseg name = "PSEG_CMA"  type = "PERI" base = "0x00B6000000" length = "0x0000008000" />
+            <pseg name = "PSEG_ROM"  type = "PERI" base = "0x00BFC00000" length = "0x0000004000" />
+
+            <proc index  = "0" >
+                <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" /> 
+                <irq type = "TIME" icuid = "1"  isr = "ISR_SWITCH" /> 
+
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY"     channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY"     channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY"     channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY"     channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY"     channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY"     channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY"     channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY"     channel = "7" /> 
+
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc> 
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1"  /> 
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "6"  />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1"  />
+            <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1" subtype = "BDV" /> 
+            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "8"  /> 
+            <periph type = "NIC"  psegname = "PSEG_NIC"  channels = "2"  />
+            <periph type = "CMA"  psegname = "PSEG_CMA"  channels = "4"  />
+            <periph type = "FBF"  psegname = "PSEG_FBF"  channels = "1"  />
+            <periph type = "ROM"  psegname = "PSEG_ROM"  channels = "1"  />
+
+        </cluster>
+
+        <cluster x = "0" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x01B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x01B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x01B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "6" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x10B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x10B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x10B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "6" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x11B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x11B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x11B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "6" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Segments used by the boot code / A[31:28] = 0x0 / Identity mapping
+- seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. The content is reused by the kernel.
+- seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader The content is not reused by the kernel.
+- seg_boot_stack is contains the stacks used by all processors during reset and boot. The content is not reused by the Kernel.
+- seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel.
+
+        <vseg name = "seg_boot_mapping"   vbase = "0x00000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB"   length = "0x00010000" binpath	= "map.bin" />
+        </vseg>
+        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_code"      type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00030000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "BUFFER" length = "0x00010000" />
+        </vseg>
+        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00090000" />
+        </vseg>
+
+*** Segments used by the kernel / A[31:28] = 0x8 
+  
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"    type = "ELF" length = "0x00020000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"    type = "ELF" length = "0x00060000" binpath = "build/kernel/kernel.elf" />
+		</vseg>
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_uncdata" type = "ELF" length = "0x00040000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"    vbase = "0x800C0000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_init"    type = "ELF" length = "0x00010000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+
+*** Segments for non replicated peripherals / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_fbf"            vbase = "0xB2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_NIC" ident = "1" >
+            <vobj name = "nic"            type = "PERI" length  = "0x00080000" /> 
+        </vseg>
+        <vseg name = "seg_cma"            vbase = "0xB6000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_CMA" ident = "1" >
+            <vobj name = "cma"            type = "PERI" length  = "0x00008000" /> 
+        </vseg>
+        <vseg name = "seg_rom"            vbase = "0xBFC00000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "rom"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+
+*** Segments for replicated ICUS / A[31:24] = 0xB0 / Increment = 0x10000 / Identity mapping in cluster 0            
+
+        <vseg name = "seg_icu_0"          vbase = "0xB0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" > 
+            <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_1"          vbase = "0xB0010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_2"          vbase = "0xB0100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_3"          vbase = "0xB0110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+
+*** segments for replicated DMAs / A[31:24] = 0xB1 / Increment = 0x10000 / Tdentity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_dma_0"          vbase = "0xB1000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_DMA" ident = "1" >
+            <vobj name = "dma_0"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_1"          vbase = "0xB1010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_1"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_2"          vbase = "0xB1100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma_2"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_3"          vbase = "0xB1110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_3"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+
+*** segments for replicated MMC / A[31:24] = 0xB8 / Increment = 0x10000 / Identity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_memc_0"         vbase = "0xB8000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" >
+            <vobj name = "memc_0"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_1"         vbase = "0xB8010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_1"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_2"         vbase = "0xB8100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_MMC" >
+            <vobj name = "memc_2"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_3"         vbase = "0xB8110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_3"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** segments for replicated schedulers / A[31:28] = 0xF / Increment = 0x10000
+*** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_1"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_2"        vbase = "0xF0100000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_2"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_3"        vbase = "0xF0110000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+***
+    </globalset> 
+
+    <vspaceset>
+
+*** For each vspace, the startname field is the name of the vobj containing the start_vector (entry point array)
+*** For each task, the startid field define the task entry point as an index in the start_vector
+*** For each task, the x,y and proclocid arguments define the task static placement
+*** For each task, the stackname field is the name of the vobj containing the task stack 
+*** For each task, the heapname field is the name of the vobj containing the task heap 
+
+        <vspace name = "router" startname = "data" > 
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "code"        type	= "ELF" length = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "__WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "data"        type	= "ELF" length = "0x00010000" binpath = "build/router/router.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C___" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "ptab"        type	= "PTAB" length  = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_prod"  vbase = "0x00700000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_prod"  type	= "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap_prod"   type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_cons"  vbase = "0x00800000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_cons"  type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_cons"   type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routA" vbase = "0x00900000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routA" type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routA"  type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routB" vbase = "0x00A00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routB" type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routB"  type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_mwmrs"       vbase = "0x00B00000" mode = "__WU" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "mwmr_in"     type = "MWMR" length = "0x00000020" init = "1" />
+                <vobj name = "mwmr_out"    type = "MWMR" length = "0x00000020" init = "1" />
+		    </vseg>
+
+            <task name = "producer" x = "0" y = "0" proclocid = "0" stackname = "stack_prod"  heapname = "heap_prod"  startid = "0" usetty = "1" />
+            <task name = "consumer" x = "0" y = "1" proclocid = "0" stackname = "stack_cons"  heapname = "heap_cons"  startid = "1" usetty = "1" />
+            <task name = "router_A" x = "1" y = "0" proclocid = "0" stackname = "stack_routA" heapname = "heap_routA" startid = "2" usetty = "1" />
+            <task name = "router_B" x = "1" y = "0" proclocid = "0" stackname = "stack_routB" heapname = "heap_routB" startid = "2" usetty = "1" />
+        </vspace>
+
+        <vspace name = "hello" startname = "data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" x = "0" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "code"	       type	= "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "data"        type	= "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C___" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" /> 
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	= "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_hello" x = "0" y = "1" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "pgcd" startname = "data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "code"        type = "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name	= "data"       type	= "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C___" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap"        type = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+
+            <task name = "main_pgcd" x = "1" y = "0" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "display" startname = "data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "code"        type	= "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "data"        type	= "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+			   </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C___" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length  = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	= "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_display" x = "1" y = "1" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" usecma = "1" />
+        </vspace>
+
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/4c_1p_iob_four.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/4c_1p_iob_four.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/4c_1p_iob_four.xml	(revision 283)
@@ -0,0 +1,365 @@
+<?xml version="1.0"?>
+
+<mapping_info signature    = "0xdeadbeef" 
+              name         = "4c_1p_iob_four" 
+              x_size       = "2" 
+              y_size       = "2" 
+              x_width      = "4"
+              y_width      = "4"
+              vspaces      = "4"
+              increment    = "0x10000" >
+
+*** The "increment" parameter is the virtual address cluster increment 
+*** The physical address cluster increment is 0x10000000000 / NB_CLUSTERS
+
+*** This first section describes an instance of the "tsar_generic_iob" architecture
+*** with 4 clusters, 1 processor per cluster and 40 bits physical address.
+
+    <clusterset>
+
+        <cluster x = "0" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x00B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x00B2000000" length = "0x0000001000" />
+
+*** Non replicated peripherals (including the ROM containing the preloader code)
+
+            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00B3000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00B4000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_NIC"  type = "PERI" base = "0x00B5000000" length = "0x0000080000" />
+            <pseg name = "PSEG_CMA"  type = "PERI" base = "0x00B6000000" length = "0x0000008000" />
+            <pseg name = "PSEG_FBF"  type = "PERI" base = "0x00B7000000" length = "0x0000004000" /> 
+            <pseg name = "PSEG_IOB"  type = "PERI" base = "0x00BE000000" length = "0x0000100000" />
+            <pseg name = "PSEG_ROM"  type = "PERI" base = "0x00BFC00000" length = "0x0000004000" />
+
+            <proc index  = "0" >
+                <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" /> 
+                <irq type = "TIME" icuid = "1"  isr = "ISR_SWITCH" /> 
+
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DEFAULT" channel = "0" />   *** should become NIC_RX
+                <irq type = "HARD" icuid = "9"  isr = "ISR_DEFAULT" channel = "1" /> 
+
+                <irq type = "HARD" icuid = "10" isr = "ISR_DEFAULT" channel = "0" />   *** should become NIC_TX
+                <irq type = "HARD" icuid = "11" isr = "ISR_DEFAULT" channel = "1" /> 
+
+                <irq type = "HARD" icuid = "12" isr = "ISR_DEFAULT" channel = "0" />   *** should become CDMA
+                <irq type = "HARD" icuid = "13" isr = "ISR_DEFAULT" channel = "1" /> 
+                <irq type = "HARD" icuid = "14" isr = "ISR_DEFAULT" channel = "2" /> 
+                <irq type = "HARD" icuid = "15" isr = "ISR_DEFAULT" channel = "3" /> 
+
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY"     channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY"     channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY"     channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY"     channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY"     channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY"     channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY"     channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY"     channel = "7" /> 
+                <irq type = "HARD" icuid = "24" isr = "ISR_TTY"     channel = "8" /> 
+                <irq type = "HARD" icuid = "25" isr = "ISR_TTY"     channel = "9" />
+                <irq type = "HARD" icuid = "26" isr = "ISR_TTY"     channel = "10" /> 
+                <irq type = "HARD" icuid = "27" isr = "ISR_TTY"     channel = "11" /> 
+                <irq type = "HARD" icuid = "28" isr = "ISR_TTY"     channel = "12" /> 
+                <irq type = "HARD" icuid = "29" isr = "ISR_TTY"     channel = "13" /> 
+                <irq type = "HARD" icuid = "30" isr = "ISR_TTY"     channel = "14" /> 
+
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc> 
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4"  /> 
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1"  />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1"  />
+            <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1" subtype = "BDV" /> 
+            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "8"  /> 
+            <periph type = "NIC"  psegname = "PSEG_NIC"  channels = "2"  />
+            <periph type = "CMA"  psegname = "PSEG_CMA"  channels = "4"  />
+            <periph type = "FBF"  psegname = "PSEG_FBF"  channels = "1"  />
+            <periph type = "IOB"  psegname = "PSEG_IOB"  channels = "1"  />
+            <periph type = "ROM"  psegname = "PSEG_ROM"  channels = "1"  />
+
+        </cluster>
+
+        <cluster x = "0" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x01B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x01B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x01B2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x10B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x10B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x10B2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x11B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x11B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x11B2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Segments used by the boot code / A[31:28] = 0x0 / Identity mapping
+- seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. The content is reused by the kernel.
+- seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader The content is not reused by the kernel.
+- seg_boot_stack is contains the stacks used by all processors during reset and boot. The content is not reused by the Kernel.
+- seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel.
+
+        <vseg name = "seg_boot_mapping"   vbase = "0x00000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB"   length = "0x00010000" binpath	= "map.bin" />
+        </vseg>
+        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_code"      type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00030000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "BUFFER" length = "0x00010000" />
+        </vseg>
+        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00090000" />
+        </vseg>
+
+*** Segments used by the kernel / A[31:28] = 0x8 
+  
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"    type = "ELF" length = "0x00020000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"    type = "ELF" length = "0x00060000" binpath = "build/kernel/kernel.elf" />
+		</vseg>
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_uncdata" type = "ELF" length = "0x00040000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"    vbase = "0x800C0000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_init"    type = "ELF" length = "0x00010000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+
+*** Segments for non replicated peripherals / A[31:28] = 0xB / Identity mapping
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+
+        <vseg name = "seg_iob"            vbase = "0xBE000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOB" ident = "1" >
+            <vobj name = "iob"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_NIC" ident = "1" >
+            <vobj name = "nic"            type = "PERI" length  = "0x00080000" /> 
+        </vseg>
+        <vseg name = "seg_cma"            vbase = "0xB6000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_CMA" ident = "1" >
+            <vobj name = "cma"            type = "PERI" length  = "0x00008000" /> 
+        </vseg>
+        <vseg name = "seg_fbf"            vbase = "0xB7000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+        <vseg name = "seg_rom"            vbase = "0xBFC00000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "rom"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+
+*** Segments for replicated ICUS / A[31:24] = 0xB0 / Increment = 0x10000 / Identity mapping in cluster 0            
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_icu_0"          vbase = "0xB0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" > 
+            <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_1"          vbase = "0xB0010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_2"          vbase = "0xB0100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_3"          vbase = "0xB0110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+
+*** segments for replicated DMAs / A[31:24] = 0xB1 / Increment = 0x10000 / Tdentity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_dma_0"          vbase = "0xB1000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_DMA" ident = "1" >
+            <vobj name = "dma_0"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_1"          vbase = "0xB1010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_1"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_2"          vbase = "0xB1100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma_2"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_3"          vbase = "0xB1110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_3"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+
+*** segments for replicated MMC / A[31:24] = 0xB2 / Increment = 0x10000 / Identity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_memc_0"         vbase = "0xB2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" >
+            <vobj name = "memc_0"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_1"         vbase = "0xB2010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_1"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_2"         vbase = "0xB2100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_MMC" >
+            <vobj name = "memc_2"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_3"         vbase = "0xB2110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_3"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** segments for replicated schedulers / A[31:28] = 0xF / Increment = 0x10000
+*** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_1"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_2"        vbase = "0xF0100000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_2"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_3"        vbase = "0xF0110000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+
+    </globalset> 
+
+    <vspaceset>
+
+*** For each vspace, the startname field is the name of the vobj containing the start_vector (entry point array)
+*** For each task, the startid field define the task entry point as an index in the start_vector
+*** For each task, the x = "0" y and proclocid arguments define the task static placement
+*** For each task, the stackname field is the name of the vobj containing the task stack 
+*** For each task, the heapname field is the name of the vobj containing the task heap 
+
+        <vspace name = "router" startname = "router_data" > 
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "router_code" type	 = "ELF" length = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "__WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "router_data" type	 = "ELF" length = "0x00010000" binpath = "build/router/router.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "ptab"        type	 = "PTAB" length  = "0x00020000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_prod"  vbase = "0x00700000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_prod"  type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap_prod"   type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_cons"  vbase = "0x00800000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_cons"  type	 = "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_cons"   type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routA" vbase = "0x00900000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routA" type	 = "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routA"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routB" vbase = "0x00A00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routB" type	 = "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routB"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_mwmrs"       vbase = "0x00B00000" mode = "__WU" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "mwmr_in"     type  = "MWMR" length = "0x00000020" init = "1" />
+                <vobj name = "mwmr_out"    type  = "MWMR" length = "0x00000020" init = "1" />
+		    </vseg>
+
+            <task name = "producer" x = "0" y = "0" proclocid = "0" stackname = "stack_prod"  heapname = "heap_prod"  startid = "0" usetty = "1" />
+            <task name = "consumer" x = "0" y = "1" proclocid = "0" stackname = "stack_cons"  heapname = "heap_cons"  startid = "1" usetty = "1" />
+            <task name = "router_A" x = "1" y = "0" proclocid = "0" stackname = "stack_routA" heapname = "heap_routA" startid = "2" usetty = "1" />
+            <task name = "router_B" x = "1" y = "1" proclocid = "0" stackname = "stack_routB" heapname = "heap_routB" startid = "2" usetty = "1" />
+        </vspace>
+
+        <vspace name = "hello" startname = "hello_data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" x = "0" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "hello_code"  type	 = "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "hello_data"  type	 = "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	 = "PTAB" length = "0x00020000" align = "13" /> 
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	 = "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	 = "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_hello" x = "0" y = "1" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "pgcd" startname = "pgcd_data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "pgcd_code"   type  = "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name	= "pgcd_data"  type	 = "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	 = "PTAB" length = "0x00020000" align = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type  = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap"        type  = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+
+            <task name = "main_pgcd" x = "1" y = "0" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "display" startname = "disp_data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "disp_code"   type	 = "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "disp_data"   type	 = "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+			</vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	 = "PTAB" length  = "0x00020000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	 = "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	 = "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_display" x = "1" y = "1" proclocid = "0" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" usecma = "1" />
+        </vspace>
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/4c_1p_iob_sort.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/4c_1p_iob_sort.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/4c_1p_iob_sort.xml	(revision 283)
@@ -0,0 +1,312 @@
+<?xml version="1.0"?>
+
+<mapping_info signature    = "0xdeadbeef" 
+              name         = "4c_1p_sort" 
+              x_size       = "2" 
+              y_size       = "2" 
+              x_width      = "4"
+              y_width      = "4"
+              vspaces      = "1"
+              increment    = "0x10000" >
+
+*** The "increment" parameter is the virtual address cluster increment 
+*** The physical address cluster increment is 0x10000000000 / NB_CLUSTERS
+
+*** This first section describes an instance of the "tsar_generic_iob" architecture
+*** with 4 clusters, 1 processor per cluster and 40 bits physical address.
+
+    <clusterset>
+
+        <cluster x = "0" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x00B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x00B2000000" length = "0x0000001000" />
+
+*** Non replicated peripherals (including the ROM containing the preloader code)
+
+            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00B3000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00B4000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_NIC"  type = "PERI" base = "0x00B5000000" length = "0x0000080000" />
+            <pseg name = "PSEG_CMA"  type = "PERI" base = "0x00B6000000" length = "0x0000008000" />
+            <pseg name = "PSEG_FBF"  type = "PERI" base = "0x00B7000000" length = "0x0000004000" /> 
+            <pseg name = "PSEG_IOB"  type = "PERI" base = "0x00BE000000" length = "0x0000100000" />
+            <pseg name = "PSEG_ROM"  type = "PERI" base = "0x00BFC00000" length = "0x0000004000" />
+
+            <proc index  = "0" >
+                <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" /> 
+                <irq type = "TIME" icuid = "1"  isr = "ISR_SWITCH" /> 
+
+                <irq type = "HARD" icuid = "8"  isr = "ISR_DEFAULT" channel = "0" />   *** should become NIC_RX
+                <irq type = "HARD" icuid = "9"  isr = "ISR_DEFAULT" channel = "1" /> 
+
+                <irq type = "HARD" icuid = "10" isr = "ISR_DEFAULT" channel = "0" />   *** should become NIC_TX
+                <irq type = "HARD" icuid = "11" isr = "ISR_DEFAULT" channel = "1" /> 
+
+                <irq type = "HARD" icuid = "12" isr = "ISR_DEFAULT" channel = "0" />   *** should become CDMA
+                <irq type = "HARD" icuid = "13" isr = "ISR_DEFAULT" channel = "1" /> 
+                <irq type = "HARD" icuid = "14" isr = "ISR_DEFAULT" channel = "2" /> 
+                <irq type = "HARD" icuid = "15" isr = "ISR_DEFAULT" channel = "3" /> 
+
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY"     channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY"     channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY"     channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY"     channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY"     channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY"     channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY"     channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY"     channel = "7" /> 
+                <irq type = "HARD" icuid = "24" isr = "ISR_TTY"     channel = "8" /> 
+                <irq type = "HARD" icuid = "25" isr = "ISR_TTY"     channel = "9" />
+                <irq type = "HARD" icuid = "26" isr = "ISR_TTY"     channel = "10" /> 
+                <irq type = "HARD" icuid = "27" isr = "ISR_TTY"     channel = "11" /> 
+                <irq type = "HARD" icuid = "28" isr = "ISR_TTY"     channel = "12" /> 
+                <irq type = "HARD" icuid = "29" isr = "ISR_TTY"     channel = "13" /> 
+                <irq type = "HARD" icuid = "30" isr = "ISR_TTY"     channel = "14" /> 
+
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc> 
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1"  /> 
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1"  />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1"  />
+            <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1"  subtype = "BDV" /> 
+            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "5"  /> 
+            <periph type = "NIC"  psegname = "PSEG_NIC"  channels = "2"  />
+            <periph type = "CMA"  psegname = "PSEG_CMA"  channels = "4"  />
+            <periph type = "FBF"  psegname = "PSEG_FBF"  channels = "1"  />
+            <periph type = "IOB"  psegname = "PSEG_IOB"  channels = "1"  />
+            <periph type = "ROM"  psegname = "PSEG_ROM"  channels = "1"  />
+
+        </cluster>
+
+        <cluster x = "0" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x01B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x01B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x01B2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x10B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x10B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x10B2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0010000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x11B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x11B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x11B2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "4" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Segments used by the boot code / A[31:28] = 0x0 / Identity mapping
+- seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. The content is reused by the kernel.
+- seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader The content is not reused by the kernel.
+- seg_boot_stack is contains the stacks used by all processors during reset and boot. The content is not reused by the Kernel.
+- seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel.
+
+        <vseg name = "seg_boot_mapping"   vbase = "0x00000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB"   length = "0x00010000" binpath	= "map.bin" />
+        </vseg>
+        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_code"      type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00030000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "BUFFER" length = "0x00010000" />
+        </vseg>
+        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00090000" />
+        </vseg>
+
+*** Segments used by the kernel / A[31:28] = 0x8 
+  
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"    type = "ELF" length = "0x00020000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"    type = "ELF" length = "0x00060000" binpath = "build/kernel/kernel.elf" />
+		</vseg>
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = '1'> 
+            <vobj name = "kernel_uncdata" type = "ELF" length = "0x00040000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"    vbase = "0x800C0000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_init"    type = "ELF" length = "0x00010000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+
+*** Segments for non replicated peripherals / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_iob"            vbase = "0xBE000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOB" ident = "1" >
+            <vobj name = "iob"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_NIC" ident = "1" >
+            <vobj name = "nic"            type = "PERI" length  = "0x00080000" /> 
+        </vseg>
+        <vseg name = "seg_cma"            vbase = "0xB6000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_CMA" ident = "1" >
+            <vobj name = "cma"            type = "PERI" length  = "0x00008000" /> 
+        </vseg>
+        <vseg name = "seg_fbf"            vbase = "0xB7000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+        <vseg name = "seg_rom"            vbase = "0xBFC00000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "rom"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+
+*** Segments for replicated ICUS / A[31:24] = 0xB0 / Increment = 0x10000 / Identity mapping in cluster 0            
+
+        <vseg name = "seg_icu_0"          vbase = "0xB0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" > 
+            <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_1"          vbase = "0xB0010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_2"          vbase = "0xB0100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_3"          vbase = "0xB0110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+
+*** segments for replicated DMAs / A[31:24] = 0xB1 / Increment = 0x10000 / Tdentity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_dma_0"          vbase = "0xB1000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_DMA" ident = "1" >
+            <vobj name = "dma_0"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_1"          vbase = "0xB1010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_1"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_2"          vbase = "0xB1100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma_2"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_3"          vbase = "0xB1110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_3"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+
+*** segments for replicated MMC / A[31:24] = 0xB2 / Increment = 0x10000 / Identity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_memc_0"         vbase = "0xB2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" >
+            <vobj name = "memc_0"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_1"         vbase = "0xB2010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_1"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_2"         vbase = "0xB2100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_MMC" >
+            <vobj name = "memc_2"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_3"         vbase = "0xB2110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_3"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** segments for replicated schedulers / A[31:28] = 0xF / Increment = 0x10000
+*** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_1"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_2"        vbase = "0xF0100000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_2"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_3"        vbase = "0xF0110000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+
+    </globalset> 
+
+    <vspaceset>
+
+*** For each vspace, the startname field is the name of the vobj containing the start_vector (entry point array)
+*** For each task, the startid field define the task entry point as an index in the start_vector
+*** For each task, the clusterid and proclocid arguments define the task static placement
+*** For each task, the stackname field is the name of the vobj containing the task stack 
+*** For each task, the heapname field is the name of the vobj containing the task heap 
+
+        <vspace name = "sort" startname = "sort_data" > 
+            <vseg name = "seg_sort_code"   vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "sort_code"   type	 = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" /> 
+            </vseg>
+            <vseg name = "seg_sort_data"   vbase = "0x00500000" mode = "__WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_data"   type	 = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" />
+            </vseg>
+            <vseg name = "seg_sort_ptab"   vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "sort_ptab"   type	 = "PTAB" length  = "0x00020000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_sort_stack0" vbase = "0x00800000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack0" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack1" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap0"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack1" vbase = "0x00A00000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack2" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack3" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap1"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack2" vbase = "0x00C00000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack4" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack5" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap2"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack3" vbase = "0x00E00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack6" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack7" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap3"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+
+            <task name = "sort_0" trdid = "0" x = "0" y = "0" proclocid = "0" stackname = "sort_stack0" heapname = "sort_heap0" startid = "0" usetty = "1" />
+            <task name = "sort_1" trdid = "1" x = "0" y = "0" proclocid = "0" stackname = "sort_stack1" heapname = "sort_heap0" startid = "0" usetty = "1" />
+            <task name = "sort_2" trdid = "2" x = "0" y = "1" proclocid = "0" stackname = "sort_stack2" heapname = "sort_heap1" startid = "0" usetty = "1" />
+            <task name = "sort_3" trdid = "3" x = "0" y = "1" proclocid = "0" stackname = "sort_stack3" heapname = "sort_heap1" startid = "0" usetty = "1" />
+            <task name = "sort_4" trdid = "4" x = "1" y = "0" proclocid = "0" stackname = "sort_stack4" heapname = "sort_heap2" startid = "0" usetty = "1" />
+            <task name = "sort_5" trdid = "5" x = "1" y = "0" proclocid = "0" stackname = "sort_stack5" heapname = "sort_heap2" startid = "0" usetty = "1" />
+            <task name = "sort_6" trdid = "6" x = "1" y = "1" proclocid = "0" stackname = "sort_stack6" heapname = "sort_heap3" startid = "0" usetty = "1" />
+            <task name = "sort_7" trdid = "7" x = "1" y = "1" proclocid = "0" stackname = "sort_stack7" heapname = "sort_heap3" startid = "0" usetty = "1" />
+        </vspace>
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/4c_1p_sort.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/4c_1p_sort.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/4c_1p_sort.xml	(revision 283)
@@ -0,0 +1,286 @@
+<?xml version="1.0"?>
+
+<mapping_info signature    = "0xdeadbeef" 
+              name         = "4c_1p_sort" 
+              x_size       = "2" 
+              y_size       = "2" 
+              x_width      = "4"
+              y_width      = "4"
+              vspaces      = "1"
+              increment    = "0x10000" >
+
+*** The "increment" parameter is the virtual address cluster increment 
+*** The physical address cluster increment is 0x10000000000 / NB_CLUSTERS
+
+*** This first section describes an instance of the "tsar_generic_iob" architecture
+*** with 4 clusters, 1 processor per cluster and 40 bits physical address.
+
+    <clusterset>
+
+        <cluster x = "0" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x00B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x00B8000000" length = "0x0000001000" />
+
+*** Non replicated peripherals (including the ROM containing the preloader code)
+
+            <pseg name = "PSEG_FBF"  type = "PERI" base = "0x00B2000000" length = "0x0000004000" /> 
+            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00B3000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00B4000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_NIC"  type = "PERI" base = "0x00B5000000" length = "0x0000080000" />
+            <pseg name = "PSEG_CMA"  type = "PERI" base = "0x00B6000000" length = "0x0000008000" />
+            <pseg name = "PSEG_ROM"  type = "PERI" base = "0x00BFC00000" length = "0x0000004000" />
+
+            <proc index  = "0" >
+                <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" /> 
+                <irq type = "TIME" icuid = "1"  isr = "ISR_SWITCH" /> 
+
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY"     channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY"     channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY"     channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY"     channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY"     channel = "4" /> 
+
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc> 
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1"  /> 
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1"  />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1"  />
+            <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1"  /> 
+            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "5" /> 
+            <periph type = "NIC"  psegname = "PSEG_NIC"  channels = "2"  />
+            <periph type = "CMA"  psegname = "PSEG_CMA"  channels = "4"  />
+            <periph type = "FBF"  psegname = "PSEG_FBF"  channels = "1"  />
+            <periph type = "ROM"  psegname = "PSEG_ROM"  channels = "1"  />
+
+        </cluster>
+
+        <cluster x = "0" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x01B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x01B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x01B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x10B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x10B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x10B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x11B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x11B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x11B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Segments used by the boot code / A[31:28] = 0x0 / Identity mapping
+- seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. The content is reused by the kernel.
+- seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader The content is not reused by the kernel.
+- seg_boot_stack is contains the stacks used by all processors during reset and boot. The content is not reused by the Kernel.
+- seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel.
+
+        <vseg name = "seg_boot_mapping"   vbase = "0x00000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB"   length = "0x00010000" binpath	= "map.bin" />
+        </vseg>
+        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_code"      type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00030000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "BUFFER" length = "0x00010000" />
+        </vseg>
+        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00090000" />
+        </vseg>
+
+*** Segments used by the kernel / A[31:28] = 0x8 
+  
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"    type = "ELF" length = "0x00020000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"    type = "ELF" length = "0x00060000" binpath = "build/kernel/kernel.elf" />
+		</vseg>
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_uncdata" type = "ELF" length = "0x00040000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"    vbase = "0x800C0000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_init"    type = "ELF" length = "0x00010000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+
+*** Segments for non replicated peripherals / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_fbf"            vbase = "0xB2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_NIC" ident = "1" >
+            <vobj name = "nic"            type = "PERI" length  = "0x00080000" /> 
+        </vseg>
+        <vseg name = "seg_cma"            vbase = "0xB6000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_CMA" ident = "1" >
+            <vobj name = "cma"            type = "PERI" length  = "0x00008000" /> 
+        </vseg>
+        <vseg name = "seg_rom"            vbase = "0xBFC00000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "rom"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+
+*** Segments for replicated ICUS / A[31:24] = 0xB0 / Increment = 0x10000 / Identity mapping in cluster 0            
+
+        <vseg name = "seg_icu_0"          vbase = "0xB0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" > 
+            <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_1"          vbase = "0xB0010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_2"          vbase = "0xB0100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_3"          vbase = "0xB0110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+
+*** segments for replicated DMAs / A[31:24] = 0xB1 / Increment = 0x10000 / Tdentity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_dma_0"          vbase = "0xB1000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_DMA" ident = "1" >
+            <vobj name = "dma_0"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_1"          vbase = "0xB1010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_1"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_2"          vbase = "0xB1100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma_2"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_3"          vbase = "0xB1110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_3"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+
+*** segments for replicated MMC / A[31:24] = 0xB8 / Increment = 0x10000 / Identity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_memc_0"         vbase = "0xB8000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" >
+            <vobj name = "memc_0"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_1"         vbase = "0xB8010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_1"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_2"         vbase = "0xB8100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_MMC" >
+            <vobj name = "memc_2"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_3"         vbase = "0xB8110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_3"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** segments for replicated schedulers / A[31:28] = 0xF / Increment = 0x10000
+*** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_1"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_2"        vbase = "0xF0100000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_2"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_3"        vbase = "0xF0110000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+***
+    </globalset> 
+
+    <vspaceset>
+
+*** For each vspace, the startname field is the name of the vobj containing the start_vector (entry point array)
+*** For each task, the startid field define the task entry point as an index in the start_vector
+*** For each task, the clusterid and proclocid arguments define the task static placement
+*** For each task, the stackname field is the name of the vobj containing the task stack 
+*** For each task, the heapname field is the name of the vobj containing the task heap 
+
+        <vspace name = "sort" startname = "sort_data" > 
+            <vseg name = "seg_sort_code"   vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "sort_code"   type	 = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" /> 
+            </vseg>
+            <vseg name = "seg_sort_data"   vbase = "0x00500000" mode = "__WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_data"   type	 = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" />
+            </vseg>
+            <vseg name = "seg_sort_ptab"   vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "sort_ptab"   type	 = "PTAB" length  = "0x00020000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_sort_stack0" vbase = "0x00800000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack0" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack1" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap0"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack1" vbase = "0x00A00000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack2" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack3" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap1"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack2" vbase = "0x00C00000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack4" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack5" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap2"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack3" vbase = "0x00E00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack6" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack7" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap3"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+
+            <task name = "sort_0" trdid = "0" x = "0" y = "0" proclocid = "0" stackname = "sort_stack0" heapname = "sort_heap0" startid = "0" usetty = "1" />
+            <task name = "sort_1" trdid = "1" x = "0" y = "0" proclocid = "0" stackname = "sort_stack1" heapname = "sort_heap0" startid = "0" usetty = "1" />
+            <task name = "sort_2" trdid = "2" x = "0" y = "1" proclocid = "0" stackname = "sort_stack2" heapname = "sort_heap1" startid = "0" usetty = "1" />
+            <task name = "sort_3" trdid = "3" x = "0" y = "1" proclocid = "0" stackname = "sort_stack3" heapname = "sort_heap1" startid = "0" usetty = "1" />
+            <task name = "sort_4" trdid = "4" x = "1" y = "0" proclocid = "0" stackname = "sort_stack4" heapname = "sort_heap2" startid = "0" usetty = "1" />
+            <task name = "sort_5" trdid = "5" x = "1" y = "0" proclocid = "0" stackname = "sort_stack5" heapname = "sort_heap2" startid = "0" usetty = "1" />
+            <task name = "sort_6" trdid = "6" x = "1" y = "1" proclocid = "0" stackname = "sort_stack6" heapname = "sort_heap3" startid = "0" usetty = "1" />
+            <task name = "sort_7" trdid = "7" x = "1" y = "1" proclocid = "0" stackname = "sort_stack7" heapname = "sort_heap3" startid = "0" usetty = "1" />
+        </vspace>
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/4c_1p_sort_chiplet.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/4c_1p_sort_chiplet.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/4c_1p_sort_chiplet.xml	(revision 283)
@@ -0,0 +1,239 @@
+<?xml version="1.0"?>
+
+<mapping_info signature    = "0xdeadbeef" 
+              name         = "4c_1p_sort_chiplet" 
+              x_size       = "2" 
+              y_size       = "2" 
+              x_width      = "4"
+              y_width      = "4"
+              vspaces      = "1"
+              increment    = "0x10000" >
+
+*** The "increment" parameter is the virtual address cluster increment 
+*** The physical address cluster increment is 0x10000000000 / NB_CLUSTERS
+
+*** This first section describes an instance of the "tsar_generic_iob" architecture
+*** with 4 clusters, 1 processor per cluster and 40 bits physical address.
+
+    <clusterset>
+
+        <cluster x = "0" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0004000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x00A2000000" length = "0x0000001000" />
+
+*** Non replicated peripherals (including the ROM containing the preloader code)
+
+            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00B3000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00B4000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_ROM"  type = "PERI" base = "0x00BFC00000" length = "0x0000008000" />
+
+            <proc index  = "0" >
+                <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" /> 
+                <irq type = "TIME" icuid = "1"  isr = "ISR_SWITCH" /> 
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc> 
+
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1"  />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1"  />
+            <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1" subtype = "SPI" /> 
+            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "1" /> 
+            <periph type = "ROM"  psegname = "PSEG_ROM"  channels = "1"  />
+
+        </cluster>
+
+        <cluster x = "0" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x01B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x01A2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x10B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x10A2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x11B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x11A2000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "1" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "1" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Segments used by the boot code / A[31:28] = 0x0 / Identity mapping
+- seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. The content is reused by the kernel.
+- seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader The content is not reused by the kernel.
+- seg_boot_stack is contains the stacks used by all processors during reset and boot. The content is not reused by the Kernel.
+- seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel.
+
+        <vseg name = "seg_boot_mapping"   vbase = "0x00000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB"   length = "0x00010000" binpath	= "map.bin" />
+        </vseg>
+        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_code"      type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00030000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "BUFFER" length = "0x00010000" />
+        </vseg>
+        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00090000" />
+        </vseg>
+
+*** Segments used by the kernel / A[31:28] = 0x8 
+  
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"    type = "ELF" length = "0x00020000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"    type = "ELF" length = "0x00060000" binpath = "build/kernel/kernel.elf" />
+		</vseg>
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_uncdata" type = "ELF" length = "0x00040000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"    vbase = "0x800C0000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_init"    type = "ELF" length = "0x00010000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+
+*** Segments for non replicated peripherals / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_rom"            vbase = "0xBFC00000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "rom"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+
+*** Segments for replicated ICUS / A[31:24] = 0xB0 / Increment = 0x10000 / Identity mapping in cluster 0            
+
+        <vseg name = "seg_icu_0"          vbase = "0xB0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" > 
+            <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_1"          vbase = "0xB0010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_2"          vbase = "0xB0100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_3"          vbase = "0xB0110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+
+*** segments for replicated MMC / A[31:24] = 0xB8 / Increment = 0x10000 / Identity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_memc_0"         vbase = "0xA2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" >
+            <vobj name = "memc_0"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_1"         vbase = "0xA2010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_1"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_2"         vbase = "0xA2100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_MMC" >
+            <vobj name = "memc_2"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_3"         vbase = "0xA2110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_3"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** segments for replicated schedulers / A[31:28] = 0xF / Increment = 0x10000
+*** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_1"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_2"        vbase = "0xF0100000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_2"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_3"        vbase = "0xF0110000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+***
+    </globalset> 
+
+    <vspaceset>
+
+*** For each vspace, the startname field is the name of the vobj containing the start_vector (entry point array)
+*** For each task, the startid field define the task entry point as an index in the start_vector
+*** For each task, the clusterid and proclocid arguments define the task static placement
+*** For each task, the stackname field is the name of the vobj containing the task stack 
+*** For each task, the heapname field is the name of the vobj containing the task heap 
+
+        <vspace name = "sort" startname = "sort_data" > 
+            <vseg name = "seg_sort_code"   vbase = "0x00400000" mode = "CXWU" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "sort_code"   type	 = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" /> 
+            </vseg>
+            <vseg name = "seg_sort_data"   vbase = "0x00500000" mode = "__WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_data"   type	 = "ELF" length = "0x00010000" binpath = "build/sort/sort.elf" />
+            </vseg>
+            <vseg name = "seg_sort_ptab"   vbase = "0x00600000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "sort_ptab"   type	 = "PTAB" length  = "0x00020000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_sort_stack0" vbase = "0x00800000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack0" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack1" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap0"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack1" vbase = "0x00A00000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack2" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack3" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap1"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack2" vbase = "0x00C00000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack4" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack5" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap2"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_sort_stack3" vbase = "0x00E00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "sort_stack6" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_stack7" type	 = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "sort_heap3"  type	 = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+
+            <task name = "sort_0" trdid = "0" x = "0" y = "0" proclocid = "0" stackname = "sort_stack0" heapname = "sort_heap0" startid = "0" usetty = "1" />
+            <task name = "sort_1" trdid = "1" x = "0" y = "0" proclocid = "0" stackname = "sort_stack1" heapname = "sort_heap0" startid = "0" usetty = "1" />
+            <task name = "sort_2" trdid = "2" x = "0" y = "1" proclocid = "0" stackname = "sort_stack2" heapname = "sort_heap1" startid = "0" usetty = "1" />
+            <task name = "sort_3" trdid = "3" x = "0" y = "1" proclocid = "0" stackname = "sort_stack3" heapname = "sort_heap1" startid = "0" usetty = "1" />
+            <task name = "sort_4" trdid = "4" x = "1" y = "0" proclocid = "0" stackname = "sort_stack4" heapname = "sort_heap2" startid = "0" usetty = "1" />
+            <task name = "sort_5" trdid = "5" x = "1" y = "0" proclocid = "0" stackname = "sort_stack5" heapname = "sort_heap2" startid = "0" usetty = "1" />
+            <task name = "sort_6" trdid = "6" x = "1" y = "1" proclocid = "0" stackname = "sort_stack6" heapname = "sort_heap3" startid = "0" usetty = "1" />
+            <task name = "sort_7" trdid = "7" x = "1" y = "1" proclocid = "0" stackname = "sort_stack7" heapname = "sort_heap3" startid = "0" usetty = "1" />
+        </vspace>
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/mappings/4c_2p_four.xml
===================================================================
--- /branch/giet_vm_ioc_drivers/mappings/4c_2p_four.xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/mappings/4c_2p_four.xml	(revision 283)
@@ -0,0 +1,356 @@
+<?xml version="1.0"?>
+
+<mapping_info signature    = "0xdeadbeef" 
+              name         = "4c_2p_four" 
+              x_size       = "2" 
+              y_size       = "2" 
+              x_width      = "4"
+              y_width      = "4"
+              vspaces      = "4"
+              increment    = "0x10000" >
+
+*** The "increment" parameter is the virtual address cluster increment 
+*** The physical address cluster increment is 0x10000000000 / NB_CLUSTERS
+
+*** This first section describes an instance of the "tsar_generic_xbar" architecture
+*** with 4 clusters, 1 processor per cluster and 40 bits physical address.
+
+    <clusterset>
+
+        <cluster x = "0" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0000000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x00B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x00B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x00B8000000" length = "0x0000001000" />
+
+*** Non replicated peripherals (including the ROM containing the preloader code)
+
+            <pseg name = "PSEG_FBF"  type = "PERI" base = "0x00B2000000" length = "0x0000004000" /> 
+            <pseg name = "PSEG_IOC"  type = "PERI" base = "0x00B3000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_TTY"  type = "PERI" base = "0x00B4000000" length = "0x0000001000" /> 
+            <pseg name = "PSEG_NIC"  type = "PERI" base = "0x00B5000000" length = "0x0000080000" />
+            <pseg name = "PSEG_CMA"  type = "PERI" base = "0x00B6000000" length = "0x0000008000" />
+            <pseg name = "PSEG_ROM"  type = "PERI" base = "0x00BFC00000" length = "0x0000004000" />
+
+            <proc index  = "0" >
+                <irq type = "SOFT" icuid = "0"  isr = "ISR_WAKUP" /> 
+                <irq type = "TIME" icuid = "2"  isr = "ISR_SWITCH" /> 
+
+                <irq type = "HARD" icuid = "16" isr = "ISR_TTY"     channel = "0" /> 
+                <irq type = "HARD" icuid = "17" isr = "ISR_TTY"     channel = "1" /> 
+                <irq type = "HARD" icuid = "18" isr = "ISR_TTY"     channel = "2" /> 
+                <irq type = "HARD" icuid = "19" isr = "ISR_TTY"     channel = "3" /> 
+                <irq type = "HARD" icuid = "20" isr = "ISR_TTY"     channel = "4" /> 
+                <irq type = "HARD" icuid = "21" isr = "ISR_TTY"     channel = "5" /> 
+                <irq type = "HARD" icuid = "22" isr = "ISR_TTY"     channel = "6" /> 
+                <irq type = "HARD" icuid = "23" isr = "ISR_TTY"     channel = "7" /> 
+
+                <irq type = "HARD" icuid = "31" isr = "ISR_IOC" /> 
+            </proc> 
+            <proc index = "1" >
+                <irq type = "SOFT" icuid = "1" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1"  /> 
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "6"  />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1"  />
+            <periph type = "IOC"  psegname = "PSEG_IOC"  channels = "1"  /> 
+            <periph type = "TTY"  psegname = "PSEG_TTY"  channels = "8"  /> 
+            <periph type = "NIC"  psegname = "PSEG_NIC"  channels = "2"  />
+            <periph type = "CMA"  psegname = "PSEG_CMA"  channels = "4"  />
+            <periph type = "FBF"  psegname = "PSEG_FBF"  channels = "1"  />
+            <periph type = "ROM"  psegname = "PSEG_ROM"  channels = "1"  />
+
+        </cluster>
+
+        <cluster x = "0" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x0100000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x01B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x01B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x01B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "2" isr = "ISR_SWITCH" />
+            </proc>
+            <proc index = "1" >
+                <irq type = "SOFT" icuid = "1" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "6" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "0" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1000000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x10B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x10B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x10B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "2" isr = "ISR_SWITCH" />
+            </proc>
+            <proc index = "1" >
+                <irq type = "SOFT" icuid = "1" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "6" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+
+        <cluster x = "1" y = "1" >
+            <pseg name = "PSEG_RAM"  type = "RAM"  base = "0x1100000000" length = "0x0001000000" />
+            <pseg name = "PSEG_XCU"  type = "PERI" base = "0x11B0000000" length = "0x0000002000" />
+            <pseg name = "PSEG_DMA"  type = "PERI" base = "0x11B1000000" length = "0x0000008000" />
+            <pseg name = "PSEG_MMC"  type = "PERI" base = "0x11B8000000" length = "0x0000001000" />
+
+            <proc index = "0" >
+                <irq type = "SOFT" icuid = "0" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "2" isr = "ISR_SWITCH" />
+            </proc>
+            <proc index = "1" >
+                <irq type = "SOFT" icuid = "1" isr = "ISR_WAKUP" />
+                <irq type = "TIME" icuid = "3" isr = "ISR_SWITCH" />
+            </proc>
+
+            <periph type = "DMA"  psegname = "PSEG_DMA"  channels = "1" />
+            <periph type = "XCU"  psegname = "PSEG_XCU"  channels = "6" />
+            <periph type = "MMC"  psegname = "PSEG_MMC"  channels = "1" />
+        </cluster>
+    </clusterset>
+
+    <globalset> 
+
+*** Segments used by the boot code / A[31:28] = 0x0 / Identity mapping
+- seg_boot_mapping is loaded by the boot-loader. It contains the mapping info. The content is reused by the kernel.
+- seg_boot_code and seg_boot data are loaded by the preloader, used by the boot-loader The content is not reused by the kernel.
+- seg_boot_stack is contains the stacks used by all processors during reset and boot. The content is not reused by the Kernel.
+- seg_boot_buffer is used by the boot-loader. It can contain a complete .elf file. The content is not reused by the kernel.
+
+        <vseg name = "seg_boot_mapping"   vbase = "0x00000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_mapping"   type = "BLOB"   length = "0x00010000" binpath	= "map.bin" />
+        </vseg>
+        <vseg name = "seg_boot_code"      vbase = "0x00010000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_code"      type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_data"      vbase = "0x00030000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_data"      type = "BUFFER" length = "0x00010000" />
+        </vseg>
+        <vseg name = "seg_boot_buffer"    vbase = "0x00040000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_buffer"    type = "BUFFER" length = "0x00020000" />
+        </vseg>
+        <vseg name = "seg_boot_stack"     vbase = "0x00060000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" ident = "1" >
+            <vobj name = "boot_stack"     type = "BUFFER" length = "0x00090000" />
+        </vseg>
+
+*** Segments used by the kernel / A[31:28] = 0x8 
+  
+        <vseg name = "seg_kernel_code"    vbase = "0x80000000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_code"    type = "ELF" length = "0x00020000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_data"    vbase = "0x80020000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_data"    type = "ELF" length = "0x00060000" binpath = "build/kernel/kernel.elf" />
+		</vseg>
+        <vseg name = "seg_kernel_uncdata" vbase = "0x80080000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_uncdata" type = "ELF" length = "0x00040000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+        <vseg name = "seg_kernel_init"    vbase = "0x800C0000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_RAM" > 
+            <vobj name = "kernel_init"    type = "ELF" length = "0x00010000" binpath = "build/kernel/kernel.elf" />
+        </vseg>
+
+*** Segments for non replicated peripherals / A[31:28] = 0xB / Identity mapping
+
+        <vseg name = "seg_fbf"            vbase = "0xB2000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_FBF" ident = "1" >
+            <vobj name = "fbf"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+        <vseg name = "seg_ioc"            vbase = "0xB3000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_IOC" ident = "1" >
+            <vobj name = "ioc"            type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_tty"            vbase = "0xB4000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_TTY" ident = "1" >
+   			<vobj name = "tty"            type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_nic"            vbase = "0xB5000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_NIC" ident = "1" >
+            <vobj name = "nic"            type = "PERI" length  = "0x00080000" /> 
+        </vseg>
+        <vseg name = "seg_cma"            vbase = "0xB6000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_CMA" ident = "1" >
+            <vobj name = "cma"            type = "PERI" length  = "0x00008000" /> 
+        </vseg>
+        <vseg name = "seg_rom"            vbase = "0xBFC00000" mode = "CXW_" x = "0" y = "0" psegname = "PSEG_ROM" ident = "1" >
+            <vobj name = "rom"            type = "PERI" length  = "0x00004000" /> 
+        </vseg>
+
+*** Segments for replicated ICUS / A[31:24] = 0xB0 / Increment = 0x10000 / Identity mapping in cluster 0            
+
+        <vseg name = "seg_icu_0"          vbase = "0xB0000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_XCU" ident = "1" > 
+            <vobj name = "icu_0"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_1"          vbase = "0xB0010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_1"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_2"          vbase = "0xB0100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_2"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+        <vseg name = "seg_icu_3"          vbase = "0xB0110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_XCU" > 
+            <vobj name = "icu_3"          type = "PERI" length  = "0x00001000" /> 
+        </vseg>
+
+*** segments for replicated DMAs / A[31:24] = 0xB1 / Increment = 0x10000 / Tdentity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_dma_0"          vbase = "0xB1000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_DMA" ident = "1" >
+            <vobj name = "dma_0"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_1"          vbase = "0xB1010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_1"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_2"          vbase = "0xB1100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_DMA" >
+            <vobj name = "dma_2"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_dma_3"          vbase = "0xB1110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_DMA" >
+            <vobj name = "dma_3"          type = "PERI" length  = "0x00008000" />
+        </vseg>
+
+*** segments for replicated MMC / A[31:24] = 0xB8 / Increment = 0x10000 / Identity mapping in cluster 0
+*** The peripheral type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_memc_0"         vbase = "0xB8000000" mode = "__W_" x = "0" y = "0" psegname = "PSEG_MMC" ident = "1" >
+            <vobj name = "memc_0"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_1"         vbase = "0xB8010000" mode = "__W_" x = "0" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_1"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_2"         vbase = "0xB8100000" mode = "__W_" x = "1" y = "0" psegname = "PSEG_MMC" >
+            <vobj name = "memc_2"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+        <vseg name = "seg_memc_3"         vbase = "0xB8110000" mode = "__W_" x = "1" y = "1" psegname = "PSEG_MMC" >
+            <vobj name = "memc_3"         type = "PERI" length  = "0x00001000" />
+        </vseg>
+
+*** segments for replicated schedulers / A[31:28] = 0xF / Increment = 0x10000
+*** The type must be entirely defined by the 8 virtual address MSB bits (mask_type = 0xFF000000)
+*** The cluster id must be encoded in the next 8 virtual address bits (cluster_mask = 0x00FF0000)
+
+        <vseg name = "seg_sched_0"        vbase = "0xF0000000" mode = "C_W_" x = "0" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_0"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_1"        vbase = "0xF0010000" mode = "C_W_" x = "0" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_1"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_2"        vbase = "0xF0100000" mode = "C_W_" x = "1" y = "0" psegname = "PSEG_RAM" >
+            <vobj name = "sched_2"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+        <vseg name = "seg_sched_3"        vbase = "0xF0110000" mode = "C_W_" x = "1" y = "1" psegname = "PSEG_RAM" >
+            <vobj name = "sched_3"        type = "SCHED" length  = "0x00008000" />
+        </vseg>
+***
+    </globalset> 
+
+    <vspaceset>
+
+*** For each vspace, the startname field is the name of the vobj containing the start_vector (entry point array)
+*** For each task, the startid field define the task entry point as an index in the start_vector
+*** For each task, the x,y and proclocid arguments define the task static placement
+*** For each task, the stackname field is the name of the vobj containing the task stack 
+*** For each task, the heapname field is the name of the vobj containing the task heap 
+
+        <vspace name = "router" startname = "data" > 
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "code"        type	= "ELF" length = "0x00010000" binpath = "build/router/router.elf" /> 
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "__WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "data"        type	= "ELF" length = "0x00010000" binpath = "build/router/router.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C___" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "ptab"        type	= "PTAB" length  = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack_prod"  vbase = "0x00700000" mode = "C_WU" x = "0" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack_prod"  type	= "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap_prod"   type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_cons"  vbase = "0x00800000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_cons"  type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_cons"   type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routA" vbase = "0x00900000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routA" type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routA"  type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_stack_routB" vbase = "0x00A00000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "stack_routB" type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap_routB"  type	= "BUFFER" length = "0x00010000" /> 
+            </vseg>
+            <vseg name = "seg_mwmrs"       vbase = "0x00B00000" mode = "__WU" x = "0" y = "0" psegname = "PSEG_RAM" > 
+                <vobj name = "mwmr_in"     type = "MWMR" length = "0x00000020" init = "1" />
+                <vobj name = "mwmr_out"    type = "MWMR" length = "0x00000020" init = "1" />
+		    </vseg>
+
+            <task name = "producer" x = "0" y = "0" proclocid = "0" stackname = "stack_prod"  heapname = "heap_prod"  startid = "0" usetty = "1" />
+            <task name = "consumer" x = "0" y = "1" proclocid = "0" stackname = "stack_cons"  heapname = "heap_cons"  startid = "1" usetty = "1" />
+            <task name = "router_A" x = "1" y = "0" proclocid = "0" stackname = "stack_routA" heapname = "heap_routA" startid = "2" usetty = "1" />
+            <task name = "router_B" x = "1" y = "1" proclocid = "0" stackname = "stack_routB" heapname = "heap_routB" startid = "2" usetty = "1" />
+        </vspace>
+
+        <vspace name = "hello" startname = "data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" x = "0" y = "1" psegname = "PSEG_RAM" > 
+                <vobj name = "code"	       type	= "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "data"        type	= "ELF" length = "0x00010000" binpath = "build/hello/hello.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C___" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" /> 
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "0" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	= "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_hello" x = "0" y = "1" proclocid = "1" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "pgcd" startname = "data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "code"        type = "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name	= "data"       type	= "ELF" length = "0x00010000" binpath = "build/pgcd/pgcd.elf" />
+            </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C___" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length = "0x00012000" align = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "1" y = "0" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type = "BUFFER" length = "0x00010000" /> 
+                <vobj name = "heap"        type = "BUFFER" length = "0x00010000" /> 
+            </vseg>
+
+            <task name = "main_pgcd" x = "1" y = "0" proclocid = "1" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" />
+        </vspace>
+
+        <vspace name = "display" startname = "data" >
+            <vseg name = "seg_code"        vbase = "0x00400000" mode = "CX_U" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "code"        type	= "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+            </vseg>
+            <vseg name = "seg_data"        vbase = "0x00500000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "data"        type	= "ELF" length = "0x00010000" binpath = "build/display/display.elf" />
+			   </vseg>
+            <vseg name = "seg_ptab"        vbase = "0x00600000" mode = "C___" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "ptab"        type	= "PTAB" length  = "0x00012000" align   = "13" />
+            </vseg>
+            <vseg name = "seg_stack"       vbase = "0x00700000" mode = "C_WU" x = "1" y = "1" psegname = "PSEG_RAM" >
+                <vobj name = "stack"       type	= "BUFFER" length = "0x00010000" />
+                <vobj name = "heap"        type	= "BUFFER" length = "0x00010000" />
+            </vseg>
+
+            <task name = "main_display" x = "1" y = "1" proclocid = "1" stackname = "stack" heapname = "heap" startid = "0" usetty = "1" usecma = "1" />
+        </vspace>
+
+    </vspaceset>
+</mapping_info>
Index: /branch/giet_vm_ioc_drivers/memo/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/Makefile	(revision 283)
@@ -0,0 +1,20 @@
+SRCS += $(wildcard src/*.cpp)
+SRCS += $(wildcard src/libelfpp/*)
+SRCS += main.cpp
+
+HDRS += $(wildcard include/*)
+HDRS += $(wildcard include/libelfpp/elfpp/*)
+HDRS += $(wildcard include/libelfpp/dpp/*)
+
+INCLUDES = -Iinclude/libelfpp -Iinclude/libelfpp/elfpp -Iinclude/ -I../xml
+memo.x: $(SRCS) $(HDRS)
+	g++ -Wall -g -DDISTRIBUTED_SCHEDULERS   $(SRCS) $(INCLUDES) -o memo.x
+
+debug: $(SRCS) $(HDRS)
+	g++ -Wall -DMOVER_DEBUG -g  $(SRCS) $(INCLUDES) -o debug.x
+
+check:
+	test/check.sh
+
+clean:
+	rm -f *.x
Index: /branch/giet_vm_ioc_drivers/memo/TODO
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/TODO	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/TODO	(revision 283)
@@ -0,0 +1,3 @@
++ Support for debug info
++ Search the sections by name, the name should correspond to vobj->name and the adresse should correspond to vseg->addresse
++ Documentation
Index: /branch/giet_vm_ioc_drivers/memo/include/exception.h
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/exception.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/exception.h	(revision 283)
@@ -0,0 +1,92 @@
+/* -*- c++ -*-
+ *
+ * Copyright (c) UPMC, Lip6, Asim
+ *      copy of the soclib exception file, original writer:
+ *          Nicolas Pouillon <nipo@ssji.net>, 2007
+ *      modified by:
+ *         Mohamed Lamine Karaoui <Mohamed.Karaoui@lip6.fr>, 2012
+ *
+ */
+
+#ifndef _EXCEPTION_H_
+#define _EXCEPTION_H_
+
+#include <exception>
+#include <string>
+#include <iostream>
+
+namespace exception {
+
+class Exception
+    : public std::exception
+{
+    std::string m_type;
+    std::string m_message;
+
+public:
+    Exception( const std::string &type,
+               const std::string &message )
+            : m_type(type), m_message(message)
+    {}
+
+    virtual ~Exception() throw()
+    {
+    }
+
+    virtual const char * what() const throw()
+    {
+        return m_message.c_str();
+    }
+
+    void print( std::ostream &o ) const
+    {
+        o << "<soclib::exception::" << m_type << ": " << m_message << ">";
+    }
+
+    friend std::ostream &operator << (std::ostream &o, const Exception &e)
+    {
+        e.print(o);
+        return o;
+    }
+};
+
+class ValueError
+    : public Exception
+{
+public:
+    ValueError( const std::string &message )
+            : Exception( "ValueError", message )
+    {}
+};
+
+class Collision
+    : public Exception
+{
+public:
+    Collision( const std::string &message )
+            : Exception( "Collision", message )
+    {}
+};
+
+class RunTimeError
+    : public Exception
+{
+public:
+    RunTimeError( const std::string &message )
+            : Exception( "RunTimeError", message )
+    {}
+};
+
+}
+
+#endif /* SOCLIB_EXCEPTION_H_ */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/Makefile.am
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/Makefile.am	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/Makefile.am	(revision 283)
@@ -0,0 +1,6 @@
+
+pkgincludedir = $(includedir)/dpp
+
+pkginclude_HEADERS = delegate foreach fstring interval_set	\
+	linked_list ref weak_ptr vector_pool xml vlarray bitfield
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/bitfield
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/bitfield	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/bitfield	(revision 283)
@@ -0,0 +1,174 @@
+/* -*- c++ -*-
+
+   C++ bitfield alias class
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2011 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_BITFIELD_HH_
+#define DPP_BITFIELD_HH_
+
+#include <stdint.h>
+
+/** @file @module{Bitfield alias} */
+
+namespace dpp {
+
+#ifndef  DPP_BITFIELD_SWAP
+  /** @This globally changes swap mask used by @ref bitfield classes
+      by xoring with the swap mask value. */
+# define DPP_BITFIELD_SWAP 0
+#endif
+
+  /** @internal */
+  template <typename X, unsigned int swap_mask>
+  inline X _bitfield_swap(X x)
+  {
+    unsigned int m = swap_mask ^ (DPP_BITFIELD_SWAP);
+
+    if (m & 1)
+      x = ((x & 0x5555555555555555ULL) << 1)  | ((x & 0xaaaaaaaaaaaaaaaaULL) >> 1);
+    if (m & 2)
+      x = ((x & 0x3333333333333333ULL) << 2)  | ((x & 0xccccccccccccccccULL) >> 2);
+    if (m & 4)
+      x = ((x & 0x0f0f0f0f0f0f0f0fULL) << 4)  | ((x & 0xf0f0f0f0f0f0f0f0ULL) >> 4);
+    if (sizeof(X) > 8 && (m & 8))
+      x = ((x & 0x00ff00ff00ff00ffULL) << 8)  | ((x & 0xff00ff00ff00ff00ULL) >> 8);
+    if (sizeof(X) > 16 && (m & 16))
+      x = ((x & 0x0000ffff0000ffffULL) << 16) | ((x & 0xffff0000ffff0000ULL) >> 16);
+    if (sizeof(X) > 32 && (m & 32))
+      x = ((x & 0x00000000ffffffffULL) << 32) | ((x & 0xffffffff00000000ULL) >> 32);
+
+    return x;
+  }
+
+#define _DPP_BITFIELD(C, X)						\
+  class C								\
+  {									\
+    static const X mask = ((1 << width) - 1);				\
+    static const X smask = mask << position;				\
+									\
+  public:								\
+									\
+    /** @This creates a bitfield alias object for the given integer. */	\
+    C(X &x)								\
+      : _x(x)								\
+    {									\
+    }									\
+									\
+    /** @This extracts bits from given integer. */			\
+    static const X get(X x)						\
+    {									\
+      return (_bitfield_swap<X, swap_mask>(x) >> position) & mask;	\
+    }									\
+									\
+    /** @This sets bits in referenced integer to given value. */	\
+    static void set(X &v, X x)						\
+    {									\
+      static const X wmask = _bitfield_swap<X, swap_mask>(smask);	\
+      x = _bitfield_swap<X, swap_mask>(x << position);			\
+      v = (v & ~wmask) | (x & wmask);					\
+    }									\
+									\
+    /** @This extracts bits from aliased integer. */			\
+    operator X () const							\
+    {									\
+      return get(_x);							\
+    }									\
+									\
+    /** @This sets bits in aliased integer to given value. */		\
+    X operator=(X x)							\
+    {									\
+      set(_x, x);							\
+      return x;								\
+    }									\
+									\
+  private:								\
+    X &_x;								\
+  }
+
+  /** @short Generic bitfield alias class
+      @module {Bitfield alias}
+      @header dpp/bitfield
+      @main
+
+      @This can be used to declare an alias which permit convenient
+      access to specified bits range inside an integer value.
+
+      This class requires the integer type as parameter, other classes
+      are available for 8, 16, 32 and 64 bits, signed and unsigned
+      integer types.
+
+      This class exposes bits at specified @tt position and @tt width
+      in aliased integer value.
+
+      @section {Bits swapping}
+
+      An additional @tt swap_mask parameter can be used to perform a
+      bits permutation on accessed integer. Each bit in the mask specify
+      size of swapped bit packets; for instance a mask value of
+      (8+16+32) performs a bytes swap on 32 bits values.
+
+      The value of the @ref DPP_BITFIELD_SWAP macro is xored with the
+      swap mask. Its default value is 0 and it can be defined before
+      including the @tt bitfield header. This allows globally
+      inverting swap mask depending on processor endianness.
+
+      @end section
+   */
+  template <typename X,
+	    unsigned int position,
+	    unsigned int width = 1,
+	    unsigned int swap_mask = 0>
+  _DPP_BITFIELD(bitfield, X);
+
+
+#define _DPP_BITFIELD_INT(u, s, n, t)					\
+  /** @short s bits u bitfield alias class				\
+      @module {Bitfield alias}						\
+      @header dpp/bitfield						\
+									\
+      @This can be used to declare an alias which permit convenient	\
+      access to specified bits range inside an integer value.		\
+									\
+      This class is designed to work with s bits u values. See the	\
+      @ref bitfield class documentation for details.			\
+  */									\
+  template <unsigned int position,					\
+	    unsigned int width = 1,					\
+	    unsigned int swap_mask = 0>					\
+  _DPP_BITFIELD(bitfield_##n, t);
+
+  _DPP_BITFIELD_INT(unsigned, 8,  u8,  uint8_t);
+  _DPP_BITFIELD_INT(signed, 8,  s8,  int8_t);
+  _DPP_BITFIELD_INT(unsigned, 16, u16, uint16_t);
+  _DPP_BITFIELD_INT(signed, 16, s16, int16_t);
+  _DPP_BITFIELD_INT(unsigned, 32, u32, uint32_t);
+  _DPP_BITFIELD_INT(signed, 32, s32, int32_t);
+  _DPP_BITFIELD_INT(unsigned, 64, u64, uint64_t);
+  _DPP_BITFIELD_INT(signed, 64, s64, int64_t);
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/delegate
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/delegate	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/delegate	(revision 283)
@@ -0,0 +1,1743 @@
+/* -*- c++ -*-
+
+   C++ delegate classes
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2008-2011 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_DELEGATE_HH_
+#define DPP_DELEGATE_HH_
+
+#include <iostream>
+
+/** @file @module{Delegates} */
+
+namespace dpp {
+
+#ifndef _DPP_DR106
+  /** @internal Workaround for c++ DR 106, strip reference */
+  template <class X>
+  struct _dr106
+  {
+    typedef X type;
+  };
+
+  /** @internal */
+  template <class X>
+  struct _dr106<X &>
+  {
+    typedef X type;
+  };
+
+  /** @internal */
+# define _DPP_DR106(x) typename _dr106<x>::type
+#endif
+
+  //////////////////////////////////////////////////////////////////////
+  //	delegate base class
+  //////////////////////////////////////////////////////////////////////
+
+  /**
+     @short Delegates base class
+     @main
+     @header dpp/delegate
+
+     All other classes in the @ref +Delegates module inherit from this
+     class. This enables passing delegates pointers and references to
+     functions in a generic and interchangeable manner.
+
+     Actual implementations for different parameters count are located
+     in class specializations.
+
+     Maximum number of arguments is defined by the @ref
+     #DPP_DELEGATE_ARGC macro.
+  */
+  template <typename prototype>
+  class delegate
+  {
+  };
+
+#ifndef DPP_DELEGATE_ARGC
+  /** @This defines maximum number of arguments handled by delegate
+      classes. It can be defined before inclusion of the header so
+      that class specialization declarations take place to handle up
+      to 8 arguments. The default value is 4. */
+# define DPP_DELEGATE_ARGC 4
+#endif
+
+#define _DPP_DELEGATE(n)				\
+  template <typename R _DPP_DELEGATE_TARGS(n)>		\
+  class delegate < R (_DPP_DELEGATE_PARGS(n)) >		\
+  {							\
+    virtual R call (_DPP_DELEGATE_CARGS(n)) const = 0;	\
+							\
+  public:						\
+    _DPP_DELEGATE_TDEFS(n); /* args typedefs */		\
+    virtual bool valid() const = 0;			\
+    virtual ~delegate() {}				\
+							\
+    R operator() (_DPP_DELEGATE_CARGS(n)) const		\
+    {							\
+      return call (_DPP_DELEGATE_IARGS(n));		\
+    }							\
+							\
+  };
+
+  //////////////////////////////////////////////////////////////////////
+  //	function pointer delegate class
+  //////////////////////////////////////////////////////////////////////
+
+  /**
+     @short Function pointer delegate class
+     @main
+     @header dpp/delegate
+
+     This delegate class embeds a pointer to a global or static member
+     function.
+
+     Actual implementations for different parameters count are located
+     in class specializations.
+
+     Maximum number of handled arguments is controlled by the @ref
+     #DPP_DELEGATE_ARGC macro.
+
+     Usage example:
+     @example test/test_delegate.cc:func1
+     @example test/test_delegate.cc:func2
+
+     @see delegate_member
+     @see delegate_member_this
+  */
+  template <typename prototype>
+  class delegate_func : public delegate<prototype>
+  {
+  };
+
+#define _DPP_DELEGATE_FUNC(n)						\
+  template <typename R _DPP_DELEGATE_TARGS(n)>				\
+  class delegate_func < R (_DPP_DELEGATE_PARGS(n)) >			\
+    : public delegate< R (_DPP_DELEGATE_PARGS(n)) >			\
+  {									\
+    typedef R prototype (_DPP_DELEGATE_PARGS(n));			\
+									\
+  public:								\
+    delegate_func()							\
+      : _func(0)							\
+      {									\
+      }									\
+									\
+    delegate_func(prototype *p)						\
+      : _func(p)							\
+      {									\
+      }									\
+									\
+    bool valid() const							\
+    {									\
+      return _func;							\
+    }									\
+									\
+    R operator()(_DPP_DELEGATE_CARGS(n)) const				\
+    {									\
+      return delegate_func::call (_DPP_DELEGATE_IARGS(n));		\
+    }									\
+									\
+  private:								\
+									\
+    R call (_DPP_DELEGATE_CARGS(n)) const				\
+    {									\
+      return _func (_DPP_DELEGATE_IARGS(n));				\
+    }									\
+									\
+    prototype *_func;							\
+  };
+
+  //////////////////////////////////////////////////////////////////////
+  //	member function pointer delegate classes
+  //////////////////////////////////////////////////////////////////////
+
+  /**
+     @short Member function pointer delegate class
+     @header dpp/delegate
+     @main
+
+     This delegate class embeds a pointer to an object and take a
+     member function to call as template argument.
+
+     Actual implementations for different parameters count are located
+     in class specializations.
+
+     Maximum number of handled arguments is controlled by the @ref
+     #DPP_DELEGATE_ARGC macro.
+
+     Usage example:
+     @example test/test_delegate.cc:member1
+     @example test/test_delegate.cc:member2
+
+     Delegate with @tt const member function type is only supported by
+     gcc 4.4 and clang compilers.
+
+     @see delegate_member_this
+     @see delegate_func
+  */
+  template <class O, typename prototype, prototype O::*F>
+  class delegate_member : public delegate<prototype>
+  {
+  };
+
+#define _DPP_DELEGATE_MEMBER_(n, cst)					\
+  template <class O, typename R _DPP_DELEGATE_TARGS(n),			\
+	    R (O::*F)(_DPP_DELEGATE_PARGS(n)) cst >			\
+  class delegate_member < O, R (_DPP_DELEGATE_PARGS(n)) cst, F >	\
+    : public delegate< R (_DPP_DELEGATE_PARGS(n)) >			\
+  {									\
+  public:								\
+									\
+    delegate_member()							\
+      : _obj(0)								\
+      {									\
+      }									\
+									\
+    delegate_member(O &obj)						\
+      : _obj(&obj)							\
+      {									\
+      }									\
+									\
+    bool valid() const							\
+    {									\
+      return _obj;							\
+    }									\
+									\
+    R operator()(_DPP_DELEGATE_CARGS(n)) const				\
+    {									\
+      return delegate_member::call(_DPP_DELEGATE_IARGS(n));		\
+    }									\
+									\
+  private:								\
+    R call (_DPP_DELEGATE_CARGS(n)) const				\
+    {									\
+      return (_obj->*F)(_DPP_DELEGATE_IARGS(n));			\
+    }									\
+									\
+    O *_obj;								\
+  };
+
+#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || (__GNUC__ > 4)) && !defined(__INTEL_COMPILER)
+# define _DPP_DELEGATE_MEMBER(n)		\
+  _DPP_DELEGATE_MEMBER_(n,)                     \
+  _DPP_DELEGATE_MEMBER_(n, const)
+#else
+# define _DPP_DELEGATE_MEMBER(n)		\
+  _DPP_DELEGATE_MEMBER_(n,)		
+#endif
+
+  /** @internal contains typedef with prototype without first argument */
+  template <typename prototype>
+  struct delegate_member_this_pm1
+  {
+  };
+
+  /** @internal */
+  template <typename A>
+  struct _delegate_member_this_ptr
+  {
+    static A & get(A &a)
+    {
+      return a;
+    }
+  };
+
+  /** @internal */
+  template <typename A>
+  struct _delegate_member_this_ptr<A *>
+  {
+    static A & get(A *a)
+    {
+      return *a;
+    }
+  };
+
+  /** @internal */
+  template <typename A>
+  struct _delegate_member_this_type { typedef A t; };
+  /** @internal */
+  template <typename A>
+  struct _delegate_member_this_type<A *> { typedef A t; };
+  /** @internal */
+  template <typename A>
+  struct _delegate_member_this_type<A &> { typedef A t; };
+
+  /**
+     @short Member function pointer delegate class
+     @header dpp/delegate
+     @prototype template <typename prototype, prototype_without_1st_arg O::*F>
+     @main
+
+     This delegate takes a member function to call as template
+     argument and invoke this function on object passed as first
+     delegate argument. Object argument may be a reference or a pointer.
+
+     Actual implementations for different parameters count are located
+     in class specializations.
+
+     Maximum number of handled arguments is controlled by the @ref
+     #DPP_DELEGATE_ARGC macro.
+
+     Usage example:
+     @example test/test_delegate.cc:member1
+     Use with reference argument:
+     @example test/test_delegate.cc:member_arg
+     Use with pointer argument:
+     @example test/test_delegate.cc:member_arg2
+
+     Delegate with @tt const member function type is only supported by
+     gcc 4.4 and clang compilers.
+
+     @see delegate_member
+     @see delegate_func
+   */
+  template <typename prototype, typename delegate_member_this_pm1<prototype>::p
+             (_delegate_member_this_type<typename delegate_member_this_pm1<prototype>::a0_t>::t::*F)>
+  class delegate_member_this : public delegate<prototype>
+  {
+  };
+
+
+#define _DPP_DELEGATE_MEMBER_THIS_(n, cst)				\
+									\
+  /** @internal */							\
+  template <typename R _DPP_DELEGATE_TARGS(n) >				\
+  struct delegate_member_this_pm1 < R (_DPP_DELEGATE_PARGS(n)) cst >	\
+  {									\
+    typedef A0 a0_t;							\
+    typedef R p(_DPP_DELEGATE_PARGS_NOT0(n)) cst;			\
+  };									\
+									\
+  template <typename R _DPP_DELEGATE_TARGS(n),				\
+	    R (_delegate_member_this_type<A0>::t::*F)			\
+	      (_DPP_DELEGATE_PARGS_NOT0(n)) cst >			\
+  class delegate_member_this < R (_DPP_DELEGATE_PARGS(n)) cst, F >	\
+    : public delegate< R (_DPP_DELEGATE_PARGS(n)) >			\
+  {									\
+  public:								\
+									\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    R operator()(_DPP_DELEGATE_CARGS(n)) const				\
+    {									\
+      return delegate_member_this::call(_DPP_DELEGATE_IARGS(n));		\
+    }									\
+									\
+  private:								\
+    R call (_DPP_DELEGATE_CARGS(n)) const				\
+    {									\
+      return (_delegate_member_this_ptr<A0>::get(a0)			\
+	      .*F)(_DPP_DELEGATE_IARGS_NOT0(n));			\
+    }									\
+  };
+
+#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || (__GNUC__ > 4)) && !defined(__INTEL_COMPILER)
+#define _DPP_DELEGATE_MEMBER_THIS(n)                    \
+  _DPP_DELEGATE_MEMBER_THIS_(n,)			\
+  _DPP_DELEGATE_MEMBER_THIS_(n, const)
+#else
+#define _DPP_DELEGATE_MEMBER_THIS(n)                    \
+  _DPP_DELEGATE_MEMBER_THIS_(n,)			
+#endif
+
+  //////////////////////////////////////////////////////////////////////
+  //	delegate bind class
+  //////////////////////////////////////////////////////////////////////
+
+  /** Specify delegate argument positions. */
+  enum delegate_args_mask_e {
+    arg1st = 1,
+    arg2nd = 2,
+    arg3rd = 4,
+    arg4th = 8,
+    arg5th = 16,
+    arg6th = 32,
+    arg7th = 64,
+    arg8th = 128
+  };
+
+  /**
+     @short Parameter bind delegate class
+     @main
+     @header dpp/delegate
+
+     This delegate class can be used to bind some parameters of an
+     other delegate to fixed values.
+
+     Actual implementations for different parameters configurations
+     are located in class specializations.
+
+     Maximum number of handled arguments is controlled by the @ref
+     #DPP_DELEGATE_ARGC macro.
+
+     Usage example:
+     @example test/test_delegate.cc:bind1
+     @example test/test_delegate.cc:bind2
+
+     @see delegate_args_mask_e
+  */
+  template <typename base, typename prototype, int args_mask>
+  class delegate_bind : public delegate<prototype>
+  {
+  };
+
+#define _DPP_DELEGATE_BIND(args_mask, n, m, tdefs, ...)			\
+  /** @hidden */							\
+  template <typename base, typename R _DPP_DELEGATE_TARGS(n)>		\
+  class delegate_bind < base, R (_DPP_DELEGATE_PARGS(n)), args_mask >	\
+    : public delegate< R (_DPP_DELEGATE_PARGS(n)) >			\
+  {									\
+    typedef R prototype(_DPP_DELEGATE_PARGS(n));			\
+    tdefs;								\
+									\
+  public:								\
+    delegate_bind(const base &b _DPP_DELEGATE_BCARGS(m))		\
+      : _base(b) _DPP_DELEGATE_BCSTR(m)					\
+	{								\
+	}								\
+									\
+    bool valid() const							\
+    {									\
+      return _base.valid();						\
+    }									\
+									\
+    R operator()(_DPP_DELEGATE_CARGS(n)) const				\
+    {									\
+      return delegate_bind::call(_DPP_DELEGATE_IARGS(n));		\
+    }									\
+									\
+  private:								\
+									\
+    R call(_DPP_DELEGATE_CARGS(n)) const				\
+    {									\
+      return _base(__VA_ARGS__);					\
+    }									\
+									\
+    const base &_base;							\
+    _DPP_DELEGATE_BFIELD(m);						\
+  };
+
+  //////////////////////////////////////////////////////////////////////
+  //	template specializations for multiple parameters configurations
+  //////////////////////////////////////////////////////////////////////
+
+#define _DPP_DELEGATE_CM ,
+#define _DPP_DELEGATE_SC ;
+#define _DPP_DELEGATE_SP
+
+#define _DPP_DELEGATE_N0(sep, _1, _2, _3, _4, _5, _6, _7, _8)
+
+#define _DPP_DELEGATE_N1(sep, _1, _2, _3, _4, _5, _6, _7, _8) _1
+#define _DPP_DELEGATE_N1_M1(...) _DPP_DELEGATE_N0(__VA_ARGS__)
+
+#define _DPP_DELEGATE_N2(sep, _1, _2, _3, _4, _5, _6, _7, _8)	\
+  _1 _DPP_DELEGATE_##sep _2
+#define _DPP_DELEGATE_N2_M1(...) _DPP_DELEGATE_N1(__VA_ARGS__)
+
+#define _DPP_DELEGATE_N3(sep, _1, _2, _3, _4, _5, _6, _7, _8)	\
+  _1 _DPP_DELEGATE_##sep _2 _DPP_DELEGATE_##sep _3
+#define _DPP_DELEGATE_N3_M1(...) _DPP_DELEGATE_N2(__VA_ARGS__)
+
+#define _DPP_DELEGATE_N4(sep, _1, _2, _3, _4, _5, _6, _7, _8)	\
+  _1 _DPP_DELEGATE_##sep _2 _DPP_DELEGATE_##sep			\
+  _3 _DPP_DELEGATE_##sep _4
+#define _DPP_DELEGATE_N4_M1(...) _DPP_DELEGATE_N3(__VA_ARGS__)
+
+#define _DPP_DELEGATE_N5(sep, _1, _2, _3, _4, _5, _6, _7, _8)		\
+  _1 _DPP_DELEGATE_##sep _2 _DPP_DELEGATE_##sep _3 _DPP_DELEGATE_##sep	\
+  _4 _DPP_DELEGATE_##sep _5
+#define _DPP_DELEGATE_N5_M1(...) _DPP_DELEGATE_N4(__VA_ARGS__)
+
+#define _DPP_DELEGATE_N6(sep, _1, _2, _3, _4, _5, _6, _7, _8)		\
+  _1 _DPP_DELEGATE_##sep _2 _DPP_DELEGATE_##sep _3 _DPP_DELEGATE_##sep	\
+  _4 _DPP_DELEGATE_##sep _5 _DPP_DELEGATE_##sep _6
+#define _DPP_DELEGATE_N6_M1(...) _DPP_DELEGATE_N5(__VA_ARGS__)
+
+#define _DPP_DELEGATE_N7(sep, _1, _2, _3, _4, _5, _6, _7, _8)		\
+  _1 _DPP_DELEGATE_##sep _2 _DPP_DELEGATE_##sep _3 _DPP_DELEGATE_##sep	\
+  _4 _DPP_DELEGATE_##sep _5 _DPP_DELEGATE_##sep _6 _DPP_DELEGATE_##sep _7
+#define _DPP_DELEGATE_N7_M1(...) _DPP_DELEGATE_N6(__VA_ARGS__)
+
+#define _DPP_DELEGATE_N8(sep, _1, _2, _3, _4, _5, _6, _7, _8)		\
+  _1 _DPP_DELEGATE_##sep _2 _DPP_DELEGATE_##sep _3 _DPP_DELEGATE_##sep	\
+  _4 _DPP_DELEGATE_##sep _5 _DPP_DELEGATE_##sep _6 _DPP_DELEGATE_##sep	\
+  _7 _DPP_DELEGATE_##sep _8
+#define _DPP_DELEGATE_N8_M1(...) _DPP_DELEGATE_N7(__VA_ARGS__)
+
+#define _DPP_DELEGATE_PARGS(n)					\
+  _DPP_DELEGATE_N##n(CM, A0, A1, A2, A3, A4, A5, A6, A7)
+
+#define _DPP_DELEGATE_PARGS_NOT0(n)				\
+  _DPP_DELEGATE_N##n##_M1(CM, A1, A2, A3, A4, A5, A6, A7, )
+
+#define _DPP_DELEGATE_IARGS(n)					\
+  _DPP_DELEGATE_N##n(CM, a0, a1, a2, a3, a4, a5, a6, a7)
+
+#define _DPP_DELEGATE_IARGS_NOT0(n)				\
+  _DPP_DELEGATE_N##n##_M1(CM, a1, a2, a3, a4, a5, a6, a7, )
+
+#define _DPP_DELEGATE_CARGS(n)				\
+  _DPP_DELEGATE_N##n(CM, A0 a0, A1 a1, A2 a2, A3 a3,	\
+		     A4 a4, A5 a5, A6 a6, A7 a7)
+
+#define _DPP_DELEGATE_TDEFS(n)					\
+  _DPP_DELEGATE_N##n(SC, typedef A0 a0_t, typedef A1 a1_t,	\
+		     typedef A2 a2_t, typedef A3 a3_t,		\
+		     typedef A4 a4_t, typedef A5 a5_t,		\
+		     typedef A6 a6_t, typedef A7 a7_t) ;
+
+#define _DPP_DELEGATE_TDEFS(n)					\
+  _DPP_DELEGATE_N##n(SC, typedef A0 a0_t, typedef A1 a1_t,	\
+		     typedef A2 a2_t, typedef A3 a3_t,		\
+		     typedef A4 a4_t, typedef A5 a5_t,		\
+		     typedef A6 a6_t, typedef A7 a7_t) ;
+
+#define _DPP_DELEGATE_TARGS(n)				    \
+  _DPP_DELEGATE_N##n(SP,_DPP_DELEGATE_CM,,,,,,,)            \
+  _DPP_DELEGATE_N##n(CM, typename A0, typename A1,	    \
+		     typename A2, typename A3,		    \
+		     typename A4, typename A5,		    \
+		     typename A6, typename A7)
+
+#define _DPP_DELEGATE_BCARGS(n)				\
+  _DPP_DELEGATE_N##n(SP,_DPP_DELEGATE_CM,,,,,,,)		\
+  _DPP_DELEGATE_N##n(CM, B0 a0, B1 a1, B2 a2, B3 a3,	\
+		     B4 a4, B5 a5, B6 a6, B7 a7)
+
+#define _DPP_DELEGATE_BCSTR(n)					\
+  _DPP_DELEGATE_N##n(SP,_DPP_DELEGATE_CM,,,,,,,)		\
+  _DPP_DELEGATE_N##n(CM, _a0(a0), _a1(a1), _a2(a2), _a3(a3),	\
+		     _a4(a4), _a5(a5), _a6(a6), _a7(a7))
+
+#define _DPP_DELEGATE_BFIELD(n)					\
+  _DPP_DELEGATE_N##n(SC, B0 _a0, B1 _a1, B2 _a2, B3 _a3,	\
+		     B4 _a4, B5 _a5, B6 _a6, B7 _a7)
+
+#define _DPP_DELEGATE_BTDEFS_(n, _1a, _2a, _3a, _4a, \
+			      _5a, _6a, _7a, _8a, ...) \
+  _DPP_DELEGATE_N##n(SC,					\
+    typedef typename base::a##_1a##_t B0,			\
+    typedef typename base::a##_2a##_t B1,			\
+    typedef typename base::a##_3a##_t B2,			\
+    typedef typename base::a##_4a##_t B3,			\
+    typedef typename base::a##_5a##_t B4,			\
+    typedef typename base::a##_6a##_t B5,			\
+    typedef typename base::a##_7a##_t B6,			\
+    typedef typename base::a##_8a##_t B7)
+
+#define _DPP_DELEGATE_BTDEFS(n, ...) _DPP_DELEGATE_BTDEFS_(n, __VA_ARGS__,,,,,,,,,)
+
+#if DPP_DELEGATE_ARGC >= 0
+  _DPP_DELEGATE(0)
+  _DPP_DELEGATE_FUNC(0)
+  _DPP_DELEGATE_MEMBER(0)
+#endif
+
+#if DPP_DELEGATE_ARGC >= 1
+  _DPP_DELEGATE(1)
+  _DPP_DELEGATE_FUNC(1)
+  _DPP_DELEGATE_MEMBER(1)
+  _DPP_DELEGATE_MEMBER_THIS(1)
+  _DPP_DELEGATE_BIND(1, 0, 1, _DPP_DELEGATE_BTDEFS(1, 0), _a0);
+#endif
+
+#if DPP_DELEGATE_ARGC >= 2
+  _DPP_DELEGATE(2)
+  _DPP_DELEGATE_FUNC(2)
+  _DPP_DELEGATE_MEMBER(2)
+  _DPP_DELEGATE_MEMBER_THIS(2)
+  _DPP_DELEGATE_BIND(1, 1, 1, _DPP_DELEGATE_BTDEFS(1, 0), _a0, a0);
+  _DPP_DELEGATE_BIND(2, 1, 1, _DPP_DELEGATE_BTDEFS(1, 1), a0, _a0);
+  _DPP_DELEGATE_BIND(3, 0, 2, _DPP_DELEGATE_BTDEFS(2, 0, 1), _a0, _a1);
+#endif
+
+#if DPP_DELEGATE_ARGC >= 3
+  _DPP_DELEGATE(3)
+  _DPP_DELEGATE_FUNC(3)
+  _DPP_DELEGATE_MEMBER(3)
+  _DPP_DELEGATE_MEMBER_THIS(3)
+  _DPP_DELEGATE_BIND(1, 2, 1, _DPP_DELEGATE_BTDEFS(1, 0), _a0, a0, a1);
+  _DPP_DELEGATE_BIND(2, 2, 1, _DPP_DELEGATE_BTDEFS(1, 1), a0, _a0, a1);
+  _DPP_DELEGATE_BIND(3, 1, 2, _DPP_DELEGATE_BTDEFS(2, 0, 1), _a0, _a1, a0);
+  _DPP_DELEGATE_BIND(4, 2, 1, _DPP_DELEGATE_BTDEFS(1, 2), a0, a1, _a0);
+  _DPP_DELEGATE_BIND(5, 1, 2, _DPP_DELEGATE_BTDEFS(2, 0, 2), _a0, a0, _a1);
+  _DPP_DELEGATE_BIND(6, 1, 2, _DPP_DELEGATE_BTDEFS(2, 1, 2), a0, _a0, _a1);
+  _DPP_DELEGATE_BIND(7, 0, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 2), _a0, _a1, _a2);
+#endif
+
+#if DPP_DELEGATE_ARGC >= 4
+  _DPP_DELEGATE(4)
+  _DPP_DELEGATE_FUNC(4)
+  _DPP_DELEGATE_MEMBER(4)
+  _DPP_DELEGATE_MEMBER_THIS(4)
+  _DPP_DELEGATE_BIND(1, 3, 1, _DPP_DELEGATE_BTDEFS(1, 0), _a0, a0, a1, a2);
+  _DPP_DELEGATE_BIND(2, 3, 1, _DPP_DELEGATE_BTDEFS(1, 1), a0, _a0, a1, a2);
+  _DPP_DELEGATE_BIND(3, 2, 2, _DPP_DELEGATE_BTDEFS(2, 0, 1), _a0, _a1, a0, a1);
+  _DPP_DELEGATE_BIND(4, 3, 1, _DPP_DELEGATE_BTDEFS(1, 2), a0, a1, _a0, a2);
+  _DPP_DELEGATE_BIND(5, 2, 2, _DPP_DELEGATE_BTDEFS(2, 0, 2), _a0, a0, _a1, a1);
+  _DPP_DELEGATE_BIND(6, 2, 2, _DPP_DELEGATE_BTDEFS(2, 1, 2), a0, _a0, _a1, a1);
+  _DPP_DELEGATE_BIND(7, 1, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 2), _a0, _a1, _a2, a0);
+  _DPP_DELEGATE_BIND(8, 3, 1, _DPP_DELEGATE_BTDEFS(1, 3), a0, a1, a2, _a0);
+  _DPP_DELEGATE_BIND(9, 2, 2, _DPP_DELEGATE_BTDEFS(2, 0, 3), _a0, a0, a1, _a1);
+  _DPP_DELEGATE_BIND(10, 2, 2, _DPP_DELEGATE_BTDEFS(2, 1, 3), a0, _a0, a1, _a1);
+  _DPP_DELEGATE_BIND(11, 1, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 3), _a0, _a1, a0, _a2);
+  _DPP_DELEGATE_BIND(12, 2, 2, _DPP_DELEGATE_BTDEFS(2, 2, 3), a0, a1, _a0, _a1);
+  _DPP_DELEGATE_BIND(13, 1, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 3), _a0, a0, _a1, _a2);
+  _DPP_DELEGATE_BIND(14, 1, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 3), a0, _a0, _a1, _a2);
+  _DPP_DELEGATE_BIND(15, 0, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 3), _a0, _a1, _a2, _a3);
+#endif
+
+#if DPP_DELEGATE_ARGC >= 5 // mkdoc:skip
+  _DPP_DELEGATE(5)
+  _DPP_DELEGATE_FUNC(5)
+  _DPP_DELEGATE_MEMBER(5)
+  _DPP_DELEGATE_MEMBER_THIS(5)
+  _DPP_DELEGATE_BIND(1, 4, 1, _DPP_DELEGATE_BTDEFS(1, 0), _a0, a0, a1, a2, a3);
+  _DPP_DELEGATE_BIND(2, 4, 1, _DPP_DELEGATE_BTDEFS(1, 1), a0, _a0, a1, a2, a3);
+  _DPP_DELEGATE_BIND(3, 3, 2, _DPP_DELEGATE_BTDEFS(2, 0, 1), _a0, _a1, a0, a1, a2);
+  _DPP_DELEGATE_BIND(4, 4, 1, _DPP_DELEGATE_BTDEFS(1, 2), a0, a1, _a0, a2, a3);
+  _DPP_DELEGATE_BIND(5, 3, 2, _DPP_DELEGATE_BTDEFS(2, 0, 2), _a0, a0, _a1, a1, a2);
+  _DPP_DELEGATE_BIND(6, 3, 2, _DPP_DELEGATE_BTDEFS(2, 1, 2), a0, _a0, _a1, a1, a2);
+  _DPP_DELEGATE_BIND(7, 2, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 2), _a0, _a1, _a2, a0, a1);
+  _DPP_DELEGATE_BIND(8, 4, 1, _DPP_DELEGATE_BTDEFS(1, 3), a0, a1, a2, _a0, a3);
+  _DPP_DELEGATE_BIND(9, 3, 2, _DPP_DELEGATE_BTDEFS(2, 0, 3), _a0, a0, a1, _a1, a2);
+  _DPP_DELEGATE_BIND(10, 3, 2, _DPP_DELEGATE_BTDEFS(2, 1, 3), a0, _a0, a1, _a1, a2);
+  _DPP_DELEGATE_BIND(11, 2, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 3), _a0, _a1, a0, _a2, a1);
+  _DPP_DELEGATE_BIND(12, 3, 2, _DPP_DELEGATE_BTDEFS(2, 2, 3), a0, a1, _a0, _a1, a2);
+  _DPP_DELEGATE_BIND(13, 2, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 3), _a0, a0, _a1, _a2, a1);
+  _DPP_DELEGATE_BIND(14, 2, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 3), a0, _a0, _a1, _a2, a1);
+  _DPP_DELEGATE_BIND(15, 1, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 3), _a0, _a1, _a2, _a3, a0);
+  _DPP_DELEGATE_BIND(16, 4, 1, _DPP_DELEGATE_BTDEFS(1, 4), a0, a1, a2, a3, _a0);
+  _DPP_DELEGATE_BIND(17, 3, 2, _DPP_DELEGATE_BTDEFS(2, 0, 4), _a0, a0, a1, a2, _a1);
+  _DPP_DELEGATE_BIND(18, 3, 2, _DPP_DELEGATE_BTDEFS(2, 1, 4), a0, _a0, a1, a2, _a1);
+  _DPP_DELEGATE_BIND(19, 2, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 4), _a0, _a1, a0, a1, _a2);
+  _DPP_DELEGATE_BIND(20, 3, 2, _DPP_DELEGATE_BTDEFS(2, 2, 4), a0, a1, _a0, a2, _a1);
+  _DPP_DELEGATE_BIND(21, 2, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 4), _a0, a0, _a1, a1, _a2);
+  _DPP_DELEGATE_BIND(22, 2, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 4), a0, _a0, _a1, a1, _a2);
+  _DPP_DELEGATE_BIND(23, 1, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 4), _a0, _a1, _a2, a0, _a3);
+  _DPP_DELEGATE_BIND(24, 3, 2, _DPP_DELEGATE_BTDEFS(2, 3, 4), a0, a1, a2, _a0, _a1);
+  _DPP_DELEGATE_BIND(25, 2, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 4), _a0, a0, a1, _a1, _a2);
+  _DPP_DELEGATE_BIND(26, 2, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 4), a0, _a0, a1, _a1, _a2);
+  _DPP_DELEGATE_BIND(27, 1, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 4), _a0, _a1, a0, _a2, _a3);
+  _DPP_DELEGATE_BIND(28, 2, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 4), a0, a1, _a0, _a1, _a2);
+  _DPP_DELEGATE_BIND(29, 1, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 4), _a0, a0, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(30, 1, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 4), a0, _a0, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(31, 0, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 4), _a0, _a1, _a2, _a3, _a4);
+#endif
+
+#if DPP_DELEGATE_ARGC >= 6 // mkdoc:skip
+  _DPP_DELEGATE(6)
+  _DPP_DELEGATE_FUNC(6)
+  _DPP_DELEGATE_MEMBER(6)
+  _DPP_DELEGATE_MEMBER_THIS(6)
+  _DPP_DELEGATE_BIND(1, 5, 1, _DPP_DELEGATE_BTDEFS(1, 0), _a0, a0, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(2, 5, 1, _DPP_DELEGATE_BTDEFS(1, 1), a0, _a0, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(3, 4, 2, _DPP_DELEGATE_BTDEFS(2, 0, 1), _a0, _a1, a0, a1, a2, a3);
+  _DPP_DELEGATE_BIND(4, 5, 1, _DPP_DELEGATE_BTDEFS(1, 2), a0, a1, _a0, a2, a3, a4);
+  _DPP_DELEGATE_BIND(5, 4, 2, _DPP_DELEGATE_BTDEFS(2, 0, 2), _a0, a0, _a1, a1, a2, a3);
+  _DPP_DELEGATE_BIND(6, 4, 2, _DPP_DELEGATE_BTDEFS(2, 1, 2), a0, _a0, _a1, a1, a2, a3);
+  _DPP_DELEGATE_BIND(7, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 2), _a0, _a1, _a2, a0, a1, a2);
+  _DPP_DELEGATE_BIND(8, 5, 1, _DPP_DELEGATE_BTDEFS(1, 3), a0, a1, a2, _a0, a3, a4);
+  _DPP_DELEGATE_BIND(9, 4, 2, _DPP_DELEGATE_BTDEFS(2, 0, 3), _a0, a0, a1, _a1, a2, a3);
+  _DPP_DELEGATE_BIND(10, 4, 2, _DPP_DELEGATE_BTDEFS(2, 1, 3), a0, _a0, a1, _a1, a2, a3);
+  _DPP_DELEGATE_BIND(11, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 3), _a0, _a1, a0, _a2, a1, a2);
+  _DPP_DELEGATE_BIND(12, 4, 2, _DPP_DELEGATE_BTDEFS(2, 2, 3), a0, a1, _a0, _a1, a2, a3);
+  _DPP_DELEGATE_BIND(13, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 3), _a0, a0, _a1, _a2, a1, a2);
+  _DPP_DELEGATE_BIND(14, 3, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 3), a0, _a0, _a1, _a2, a1, a2);
+  _DPP_DELEGATE_BIND(15, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 3), _a0, _a1, _a2, _a3, a0, a1);
+  _DPP_DELEGATE_BIND(16, 5, 1, _DPP_DELEGATE_BTDEFS(1, 4), a0, a1, a2, a3, _a0, a4);
+  _DPP_DELEGATE_BIND(17, 4, 2, _DPP_DELEGATE_BTDEFS(2, 0, 4), _a0, a0, a1, a2, _a1, a3);
+  _DPP_DELEGATE_BIND(18, 4, 2, _DPP_DELEGATE_BTDEFS(2, 1, 4), a0, _a0, a1, a2, _a1, a3);
+  _DPP_DELEGATE_BIND(19, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 4), _a0, _a1, a0, a1, _a2, a2);
+  _DPP_DELEGATE_BIND(20, 4, 2, _DPP_DELEGATE_BTDEFS(2, 2, 4), a0, a1, _a0, a2, _a1, a3);
+  _DPP_DELEGATE_BIND(21, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 4), _a0, a0, _a1, a1, _a2, a2);
+  _DPP_DELEGATE_BIND(22, 3, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 4), a0, _a0, _a1, a1, _a2, a2);
+  _DPP_DELEGATE_BIND(23, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 4), _a0, _a1, _a2, a0, _a3, a1);
+  _DPP_DELEGATE_BIND(24, 4, 2, _DPP_DELEGATE_BTDEFS(2, 3, 4), a0, a1, a2, _a0, _a1, a3);
+  _DPP_DELEGATE_BIND(25, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 4), _a0, a0, a1, _a1, _a2, a2);
+  _DPP_DELEGATE_BIND(26, 3, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 4), a0, _a0, a1, _a1, _a2, a2);
+  _DPP_DELEGATE_BIND(27, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 4), _a0, _a1, a0, _a2, _a3, a1);
+  _DPP_DELEGATE_BIND(28, 3, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 4), a0, a1, _a0, _a1, _a2, a2);
+  _DPP_DELEGATE_BIND(29, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 4), _a0, a0, _a1, _a2, _a3, a1);
+  _DPP_DELEGATE_BIND(30, 2, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 4), a0, _a0, _a1, _a2, _a3, a1);
+  _DPP_DELEGATE_BIND(31, 1, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 4), _a0, _a1, _a2, _a3, _a4, a0);
+  _DPP_DELEGATE_BIND(32, 5, 1, _DPP_DELEGATE_BTDEFS(1, 5), a0, a1, a2, a3, a4, _a0);
+  _DPP_DELEGATE_BIND(33, 4, 2, _DPP_DELEGATE_BTDEFS(2, 0, 5), _a0, a0, a1, a2, a3, _a1);
+  _DPP_DELEGATE_BIND(34, 4, 2, _DPP_DELEGATE_BTDEFS(2, 1, 5), a0, _a0, a1, a2, a3, _a1);
+  _DPP_DELEGATE_BIND(35, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 5), _a0, _a1, a0, a1, a2, _a2);
+  _DPP_DELEGATE_BIND(36, 4, 2, _DPP_DELEGATE_BTDEFS(2, 2, 5), a0, a1, _a0, a2, a3, _a1);
+  _DPP_DELEGATE_BIND(37, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 5), _a0, a0, _a1, a1, a2, _a2);
+  _DPP_DELEGATE_BIND(38, 3, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 5), a0, _a0, _a1, a1, a2, _a2);
+  _DPP_DELEGATE_BIND(39, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 5), _a0, _a1, _a2, a0, a1, _a3);
+  _DPP_DELEGATE_BIND(40, 4, 2, _DPP_DELEGATE_BTDEFS(2, 3, 5), a0, a1, a2, _a0, a3, _a1);
+  _DPP_DELEGATE_BIND(41, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 5), _a0, a0, a1, _a1, a2, _a2);
+  _DPP_DELEGATE_BIND(42, 3, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 5), a0, _a0, a1, _a1, a2, _a2);
+  _DPP_DELEGATE_BIND(43, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 5), _a0, _a1, a0, _a2, a1, _a3);
+  _DPP_DELEGATE_BIND(44, 3, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 5), a0, a1, _a0, _a1, a2, _a2);
+  _DPP_DELEGATE_BIND(45, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 5), _a0, a0, _a1, _a2, a1, _a3);
+  _DPP_DELEGATE_BIND(46, 2, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 5), a0, _a0, _a1, _a2, a1, _a3);
+  _DPP_DELEGATE_BIND(47, 1, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 5), _a0, _a1, _a2, _a3, a0, _a4);
+  _DPP_DELEGATE_BIND(48, 4, 2, _DPP_DELEGATE_BTDEFS(2, 4, 5), a0, a1, a2, a3, _a0, _a1);
+  _DPP_DELEGATE_BIND(49, 3, 3, _DPP_DELEGATE_BTDEFS(3, 0, 4, 5), _a0, a0, a1, a2, _a1, _a2);
+  _DPP_DELEGATE_BIND(50, 3, 3, _DPP_DELEGATE_BTDEFS(3, 1, 4, 5), a0, _a0, a1, a2, _a1, _a2);
+  _DPP_DELEGATE_BIND(51, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 4, 5), _a0, _a1, a0, a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(52, 3, 3, _DPP_DELEGATE_BTDEFS(3, 2, 4, 5), a0, a1, _a0, a2, _a1, _a2);
+  _DPP_DELEGATE_BIND(53, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 4, 5), _a0, a0, _a1, a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(54, 2, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 4, 5), a0, _a0, _a1, a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(55, 1, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 4, 5), _a0, _a1, _a2, a0, _a3, _a4);
+  _DPP_DELEGATE_BIND(56, 3, 3, _DPP_DELEGATE_BTDEFS(3, 3, 4, 5), a0, a1, a2, _a0, _a1, _a2);
+  _DPP_DELEGATE_BIND(57, 2, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 4, 5), _a0, a0, a1, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(58, 2, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 4, 5), a0, _a0, a1, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(59, 1, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 4, 5), _a0, _a1, a0, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(60, 2, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 4, 5), a0, a1, _a0, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(61, 1, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 4, 5), _a0, a0, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(62, 1, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 4, 5), a0, _a0, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(63, 0, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 4, 5), _a0, _a1, _a2, _a3, _a4, _a5);
+#endif
+
+#if DPP_DELEGATE_ARGC >= 7 // mkdoc:skip
+  _DPP_DELEGATE(7)
+  _DPP_DELEGATE_FUNC(7)
+  _DPP_DELEGATE_MEMBER(7)
+  _DPP_DELEGATE_MEMBER_THIS(7)
+  _DPP_DELEGATE_BIND(1, 6, 1, _DPP_DELEGATE_BTDEFS(1, 0), _a0, a0, a1, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(2, 6, 1, _DPP_DELEGATE_BTDEFS(1, 1), a0, _a0, a1, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(3, 5, 2, _DPP_DELEGATE_BTDEFS(2, 0, 1), _a0, _a1, a0, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(4, 6, 1, _DPP_DELEGATE_BTDEFS(1, 2), a0, a1, _a0, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(5, 5, 2, _DPP_DELEGATE_BTDEFS(2, 0, 2), _a0, a0, _a1, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(6, 5, 2, _DPP_DELEGATE_BTDEFS(2, 1, 2), a0, _a0, _a1, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(7, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 2), _a0, _a1, _a2, a0, a1, a2, a3);
+  _DPP_DELEGATE_BIND(8, 6, 1, _DPP_DELEGATE_BTDEFS(1, 3), a0, a1, a2, _a0, a3, a4, a5);
+  _DPP_DELEGATE_BIND(9, 5, 2, _DPP_DELEGATE_BTDEFS(2, 0, 3), _a0, a0, a1, _a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(10, 5, 2, _DPP_DELEGATE_BTDEFS(2, 1, 3), a0, _a0, a1, _a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(11, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 3), _a0, _a1, a0, _a2, a1, a2, a3);
+  _DPP_DELEGATE_BIND(12, 5, 2, _DPP_DELEGATE_BTDEFS(2, 2, 3), a0, a1, _a0, _a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(13, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 3), _a0, a0, _a1, _a2, a1, a2, a3);
+  _DPP_DELEGATE_BIND(14, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 3), a0, _a0, _a1, _a2, a1, a2, a3);
+  _DPP_DELEGATE_BIND(15, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 3), _a0, _a1, _a2, _a3, a0, a1, a2);
+  _DPP_DELEGATE_BIND(16, 6, 1, _DPP_DELEGATE_BTDEFS(1, 4), a0, a1, a2, a3, _a0, a4, a5);
+  _DPP_DELEGATE_BIND(17, 5, 2, _DPP_DELEGATE_BTDEFS(2, 0, 4), _a0, a0, a1, a2, _a1, a3, a4);
+  _DPP_DELEGATE_BIND(18, 5, 2, _DPP_DELEGATE_BTDEFS(2, 1, 4), a0, _a0, a1, a2, _a1, a3, a4);
+  _DPP_DELEGATE_BIND(19, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 4), _a0, _a1, a0, a1, _a2, a2, a3);
+  _DPP_DELEGATE_BIND(20, 5, 2, _DPP_DELEGATE_BTDEFS(2, 2, 4), a0, a1, _a0, a2, _a1, a3, a4);
+  _DPP_DELEGATE_BIND(21, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 4), _a0, a0, _a1, a1, _a2, a2, a3);
+  _DPP_DELEGATE_BIND(22, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 4), a0, _a0, _a1, a1, _a2, a2, a3);
+  _DPP_DELEGATE_BIND(23, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 4), _a0, _a1, _a2, a0, _a3, a1, a2);
+  _DPP_DELEGATE_BIND(24, 5, 2, _DPP_DELEGATE_BTDEFS(2, 3, 4), a0, a1, a2, _a0, _a1, a3, a4);
+  _DPP_DELEGATE_BIND(25, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 4), _a0, a0, a1, _a1, _a2, a2, a3);
+  _DPP_DELEGATE_BIND(26, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 4), a0, _a0, a1, _a1, _a2, a2, a3);
+  _DPP_DELEGATE_BIND(27, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 4), _a0, _a1, a0, _a2, _a3, a1, a2);
+  _DPP_DELEGATE_BIND(28, 4, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 4), a0, a1, _a0, _a1, _a2, a2, a3);
+  _DPP_DELEGATE_BIND(29, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 4), _a0, a0, _a1, _a2, _a3, a1, a2);
+  _DPP_DELEGATE_BIND(30, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 4), a0, _a0, _a1, _a2, _a3, a1, a2);
+  _DPP_DELEGATE_BIND(31, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 4), _a0, _a1, _a2, _a3, _a4, a0, a1);
+  _DPP_DELEGATE_BIND(32, 6, 1, _DPP_DELEGATE_BTDEFS(1, 5), a0, a1, a2, a3, a4, _a0, a5);
+  _DPP_DELEGATE_BIND(33, 5, 2, _DPP_DELEGATE_BTDEFS(2, 0, 5), _a0, a0, a1, a2, a3, _a1, a4);
+  _DPP_DELEGATE_BIND(34, 5, 2, _DPP_DELEGATE_BTDEFS(2, 1, 5), a0, _a0, a1, a2, a3, _a1, a4);
+  _DPP_DELEGATE_BIND(35, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 5), _a0, _a1, a0, a1, a2, _a2, a3);
+  _DPP_DELEGATE_BIND(36, 5, 2, _DPP_DELEGATE_BTDEFS(2, 2, 5), a0, a1, _a0, a2, a3, _a1, a4);
+  _DPP_DELEGATE_BIND(37, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 5), _a0, a0, _a1, a1, a2, _a2, a3);
+  _DPP_DELEGATE_BIND(38, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 5), a0, _a0, _a1, a1, a2, _a2, a3);
+  _DPP_DELEGATE_BIND(39, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 5), _a0, _a1, _a2, a0, a1, _a3, a2);
+  _DPP_DELEGATE_BIND(40, 5, 2, _DPP_DELEGATE_BTDEFS(2, 3, 5), a0, a1, a2, _a0, a3, _a1, a4);
+  _DPP_DELEGATE_BIND(41, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 5), _a0, a0, a1, _a1, a2, _a2, a3);
+  _DPP_DELEGATE_BIND(42, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 5), a0, _a0, a1, _a1, a2, _a2, a3);
+  _DPP_DELEGATE_BIND(43, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 5), _a0, _a1, a0, _a2, a1, _a3, a2);
+  _DPP_DELEGATE_BIND(44, 4, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 5), a0, a1, _a0, _a1, a2, _a2, a3);
+  _DPP_DELEGATE_BIND(45, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 5), _a0, a0, _a1, _a2, a1, _a3, a2);
+  _DPP_DELEGATE_BIND(46, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 5), a0, _a0, _a1, _a2, a1, _a3, a2);
+  _DPP_DELEGATE_BIND(47, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 5), _a0, _a1, _a2, _a3, a0, _a4, a1);
+  _DPP_DELEGATE_BIND(48, 5, 2, _DPP_DELEGATE_BTDEFS(2, 4, 5), a0, a1, a2, a3, _a0, _a1, a4);
+  _DPP_DELEGATE_BIND(49, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 4, 5), _a0, a0, a1, a2, _a1, _a2, a3);
+  _DPP_DELEGATE_BIND(50, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 4, 5), a0, _a0, a1, a2, _a1, _a2, a3);
+  _DPP_DELEGATE_BIND(51, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 4, 5), _a0, _a1, a0, a1, _a2, _a3, a2);
+  _DPP_DELEGATE_BIND(52, 4, 3, _DPP_DELEGATE_BTDEFS(3, 2, 4, 5), a0, a1, _a0, a2, _a1, _a2, a3);
+  _DPP_DELEGATE_BIND(53, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 4, 5), _a0, a0, _a1, a1, _a2, _a3, a2);
+  _DPP_DELEGATE_BIND(54, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 4, 5), a0, _a0, _a1, a1, _a2, _a3, a2);
+  _DPP_DELEGATE_BIND(55, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 4, 5), _a0, _a1, _a2, a0, _a3, _a4, a1);
+  _DPP_DELEGATE_BIND(56, 4, 3, _DPP_DELEGATE_BTDEFS(3, 3, 4, 5), a0, a1, a2, _a0, _a1, _a2, a3);
+  _DPP_DELEGATE_BIND(57, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 4, 5), _a0, a0, a1, _a1, _a2, _a3, a2);
+  _DPP_DELEGATE_BIND(58, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 4, 5), a0, _a0, a1, _a1, _a2, _a3, a2);
+  _DPP_DELEGATE_BIND(59, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 4, 5), _a0, _a1, a0, _a2, _a3, _a4, a1);
+  _DPP_DELEGATE_BIND(60, 3, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 4, 5), a0, a1, _a0, _a1, _a2, _a3, a2);
+  _DPP_DELEGATE_BIND(61, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 4, 5), _a0, a0, _a1, _a2, _a3, _a4, a1);
+  _DPP_DELEGATE_BIND(62, 2, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 4, 5), a0, _a0, _a1, _a2, _a3, _a4, a1);
+  _DPP_DELEGATE_BIND(63, 1, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 4, 5), _a0, _a1, _a2, _a3, _a4, _a5, a0);
+  _DPP_DELEGATE_BIND(64, 6, 1, _DPP_DELEGATE_BTDEFS(1, 6), a0, a1, a2, a3, a4, a5, _a0);
+  _DPP_DELEGATE_BIND(65, 5, 2, _DPP_DELEGATE_BTDEFS(2, 0, 6), _a0, a0, a1, a2, a3, a4, _a1);
+  _DPP_DELEGATE_BIND(66, 5, 2, _DPP_DELEGATE_BTDEFS(2, 1, 6), a0, _a0, a1, a2, a3, a4, _a1);
+  _DPP_DELEGATE_BIND(67, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 6), _a0, _a1, a0, a1, a2, a3, _a2);
+  _DPP_DELEGATE_BIND(68, 5, 2, _DPP_DELEGATE_BTDEFS(2, 2, 6), a0, a1, _a0, a2, a3, a4, _a1);
+  _DPP_DELEGATE_BIND(69, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 6), _a0, a0, _a1, a1, a2, a3, _a2);
+  _DPP_DELEGATE_BIND(70, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 6), a0, _a0, _a1, a1, a2, a3, _a2);
+  _DPP_DELEGATE_BIND(71, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 6), _a0, _a1, _a2, a0, a1, a2, _a3);
+  _DPP_DELEGATE_BIND(72, 5, 2, _DPP_DELEGATE_BTDEFS(2, 3, 6), a0, a1, a2, _a0, a3, a4, _a1);
+  _DPP_DELEGATE_BIND(73, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 6), _a0, a0, a1, _a1, a2, a3, _a2);
+  _DPP_DELEGATE_BIND(74, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 6), a0, _a0, a1, _a1, a2, a3, _a2);
+  _DPP_DELEGATE_BIND(75, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 6), _a0, _a1, a0, _a2, a1, a2, _a3);
+  _DPP_DELEGATE_BIND(76, 4, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 6), a0, a1, _a0, _a1, a2, a3, _a2);
+  _DPP_DELEGATE_BIND(77, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 6), _a0, a0, _a1, _a2, a1, a2, _a3);
+  _DPP_DELEGATE_BIND(78, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 6), a0, _a0, _a1, _a2, a1, a2, _a3);
+  _DPP_DELEGATE_BIND(79, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 6), _a0, _a1, _a2, _a3, a0, a1, _a4);
+  _DPP_DELEGATE_BIND(80, 5, 2, _DPP_DELEGATE_BTDEFS(2, 4, 6), a0, a1, a2, a3, _a0, a4, _a1);
+  _DPP_DELEGATE_BIND(81, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 4, 6), _a0, a0, a1, a2, _a1, a3, _a2);
+  _DPP_DELEGATE_BIND(82, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 4, 6), a0, _a0, a1, a2, _a1, a3, _a2);
+  _DPP_DELEGATE_BIND(83, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 4, 6), _a0, _a1, a0, a1, _a2, a2, _a3);
+  _DPP_DELEGATE_BIND(84, 4, 3, _DPP_DELEGATE_BTDEFS(3, 2, 4, 6), a0, a1, _a0, a2, _a1, a3, _a2);
+  _DPP_DELEGATE_BIND(85, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 4, 6), _a0, a0, _a1, a1, _a2, a2, _a3);
+  _DPP_DELEGATE_BIND(86, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 4, 6), a0, _a0, _a1, a1, _a2, a2, _a3);
+  _DPP_DELEGATE_BIND(87, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 4, 6), _a0, _a1, _a2, a0, _a3, a1, _a4);
+  _DPP_DELEGATE_BIND(88, 4, 3, _DPP_DELEGATE_BTDEFS(3, 3, 4, 6), a0, a1, a2, _a0, _a1, a3, _a2);
+  _DPP_DELEGATE_BIND(89, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 4, 6), _a0, a0, a1, _a1, _a2, a2, _a3);
+  _DPP_DELEGATE_BIND(90, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 4, 6), a0, _a0, a1, _a1, _a2, a2, _a3);
+  _DPP_DELEGATE_BIND(91, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 4, 6), _a0, _a1, a0, _a2, _a3, a1, _a4);
+  _DPP_DELEGATE_BIND(92, 3, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 4, 6), a0, a1, _a0, _a1, _a2, a2, _a3);
+  _DPP_DELEGATE_BIND(93, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 4, 6), _a0, a0, _a1, _a2, _a3, a1, _a4);
+  _DPP_DELEGATE_BIND(94, 2, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 4, 6), a0, _a0, _a1, _a2, _a3, a1, _a4);
+  _DPP_DELEGATE_BIND(95, 1, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 4, 6), _a0, _a1, _a2, _a3, _a4, a0, _a5);
+  _DPP_DELEGATE_BIND(96, 5, 2, _DPP_DELEGATE_BTDEFS(2, 5, 6), a0, a1, a2, a3, a4, _a0, _a1);
+  _DPP_DELEGATE_BIND(97, 4, 3, _DPP_DELEGATE_BTDEFS(3, 0, 5, 6), _a0, a0, a1, a2, a3, _a1, _a2);
+  _DPP_DELEGATE_BIND(98, 4, 3, _DPP_DELEGATE_BTDEFS(3, 1, 5, 6), a0, _a0, a1, a2, a3, _a1, _a2);
+  _DPP_DELEGATE_BIND(99, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 5, 6), _a0, _a1, a0, a1, a2, _a2, _a3);
+  _DPP_DELEGATE_BIND(100, 4, 3, _DPP_DELEGATE_BTDEFS(3, 2, 5, 6), a0, a1, _a0, a2, a3, _a1, _a2);
+  _DPP_DELEGATE_BIND(101, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 5, 6), _a0, a0, _a1, a1, a2, _a2, _a3);
+  _DPP_DELEGATE_BIND(102, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 5, 6), a0, _a0, _a1, a1, a2, _a2, _a3);
+  _DPP_DELEGATE_BIND(103, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 5, 6), _a0, _a1, _a2, a0, a1, _a3, _a4);
+  _DPP_DELEGATE_BIND(104, 4, 3, _DPP_DELEGATE_BTDEFS(3, 3, 5, 6), a0, a1, a2, _a0, a3, _a1, _a2);
+  _DPP_DELEGATE_BIND(105, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 5, 6), _a0, a0, a1, _a1, a2, _a2, _a3);
+  _DPP_DELEGATE_BIND(106, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 5, 6), a0, _a0, a1, _a1, a2, _a2, _a3);
+  _DPP_DELEGATE_BIND(107, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 5, 6), _a0, _a1, a0, _a2, a1, _a3, _a4);
+  _DPP_DELEGATE_BIND(108, 3, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 5, 6), a0, a1, _a0, _a1, a2, _a2, _a3);
+  _DPP_DELEGATE_BIND(109, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 5, 6), _a0, a0, _a1, _a2, a1, _a3, _a4);
+  _DPP_DELEGATE_BIND(110, 2, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 5, 6), a0, _a0, _a1, _a2, a1, _a3, _a4);
+  _DPP_DELEGATE_BIND(111, 1, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 5, 6), _a0, _a1, _a2, _a3, a0, _a4, _a5);
+  _DPP_DELEGATE_BIND(112, 4, 3, _DPP_DELEGATE_BTDEFS(3, 4, 5, 6), a0, a1, a2, a3, _a0, _a1, _a2);
+  _DPP_DELEGATE_BIND(113, 3, 4, _DPP_DELEGATE_BTDEFS(4, 0, 4, 5, 6), _a0, a0, a1, a2, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(114, 3, 4, _DPP_DELEGATE_BTDEFS(4, 1, 4, 5, 6), a0, _a0, a1, a2, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(115, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 4, 5, 6), _a0, _a1, a0, a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(116, 3, 4, _DPP_DELEGATE_BTDEFS(4, 2, 4, 5, 6), a0, a1, _a0, a2, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(117, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 4, 5, 6), _a0, a0, _a1, a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(118, 2, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 4, 5, 6), a0, _a0, _a1, a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(119, 1, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 4, 5, 6), _a0, _a1, _a2, a0, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(120, 3, 4, _DPP_DELEGATE_BTDEFS(4, 3, 4, 5, 6), a0, a1, a2, _a0, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(121, 2, 5, _DPP_DELEGATE_BTDEFS(5, 0, 3, 4, 5, 6), _a0, a0, a1, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(122, 2, 5, _DPP_DELEGATE_BTDEFS(5, 1, 3, 4, 5, 6), a0, _a0, a1, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(123, 1, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 3, 4, 5, 6), _a0, _a1, a0, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(124, 2, 5, _DPP_DELEGATE_BTDEFS(5, 2, 3, 4, 5, 6), a0, a1, _a0, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(125, 1, 6, _DPP_DELEGATE_BTDEFS(6, 0, 2, 3, 4, 5, 6), _a0, a0, _a1, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(126, 1, 6, _DPP_DELEGATE_BTDEFS(6, 1, 2, 3, 4, 5, 6), a0, _a0, _a1, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(127, 0, 7, _DPP_DELEGATE_BTDEFS(7, 0, 1, 2, 3, 4, 5, 6), _a0, _a1, _a2, _a3, _a4, _a5, _a6);
+#endif
+
+#if DPP_DELEGATE_ARGC >= 8 // mkdoc:skip
+  _DPP_DELEGATE(8)
+  _DPP_DELEGATE_FUNC(8)
+  _DPP_DELEGATE_MEMBER(8)
+  _DPP_DELEGATE_MEMBER_THIS(8)
+  _DPP_DELEGATE_BIND(1, 7, 1, _DPP_DELEGATE_BTDEFS(1, 0), _a0, a0, a1, a2, a3, a4, a5, a6);
+  _DPP_DELEGATE_BIND(2, 7, 1, _DPP_DELEGATE_BTDEFS(1, 1), a0, _a0, a1, a2, a3, a4, a5, a6);
+  _DPP_DELEGATE_BIND(3, 6, 2, _DPP_DELEGATE_BTDEFS(2, 0, 1), _a0, _a1, a0, a1, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(4, 7, 1, _DPP_DELEGATE_BTDEFS(1, 2), a0, a1, _a0, a2, a3, a4, a5, a6);
+  _DPP_DELEGATE_BIND(5, 6, 2, _DPP_DELEGATE_BTDEFS(2, 0, 2), _a0, a0, _a1, a1, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(6, 6, 2, _DPP_DELEGATE_BTDEFS(2, 1, 2), a0, _a0, _a1, a1, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(7, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 2), _a0, _a1, _a2, a0, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(8, 7, 1, _DPP_DELEGATE_BTDEFS(1, 3), a0, a1, a2, _a0, a3, a4, a5, a6);
+  _DPP_DELEGATE_BIND(9, 6, 2, _DPP_DELEGATE_BTDEFS(2, 0, 3), _a0, a0, a1, _a1, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(10, 6, 2, _DPP_DELEGATE_BTDEFS(2, 1, 3), a0, _a0, a1, _a1, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(11, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 3), _a0, _a1, a0, _a2, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(12, 6, 2, _DPP_DELEGATE_BTDEFS(2, 2, 3), a0, a1, _a0, _a1, a2, a3, a4, a5);
+  _DPP_DELEGATE_BIND(13, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 3), _a0, a0, _a1, _a2, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(14, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 3), a0, _a0, _a1, _a2, a1, a2, a3, a4);
+  _DPP_DELEGATE_BIND(15, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 3), _a0, _a1, _a2, _a3, a0, a1, a2, a3);
+  _DPP_DELEGATE_BIND(16, 7, 1, _DPP_DELEGATE_BTDEFS(1, 4), a0, a1, a2, a3, _a0, a4, a5, a6);
+  _DPP_DELEGATE_BIND(17, 6, 2, _DPP_DELEGATE_BTDEFS(2, 0, 4), _a0, a0, a1, a2, _a1, a3, a4, a5);
+  _DPP_DELEGATE_BIND(18, 6, 2, _DPP_DELEGATE_BTDEFS(2, 1, 4), a0, _a0, a1, a2, _a1, a3, a4, a5);
+  _DPP_DELEGATE_BIND(19, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 4), _a0, _a1, a0, a1, _a2, a2, a3, a4);
+  _DPP_DELEGATE_BIND(20, 6, 2, _DPP_DELEGATE_BTDEFS(2, 2, 4), a0, a1, _a0, a2, _a1, a3, a4, a5);
+  _DPP_DELEGATE_BIND(21, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 4), _a0, a0, _a1, a1, _a2, a2, a3, a4);
+  _DPP_DELEGATE_BIND(22, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 4), a0, _a0, _a1, a1, _a2, a2, a3, a4);
+  _DPP_DELEGATE_BIND(23, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 4), _a0, _a1, _a2, a0, _a3, a1, a2, a3);
+  _DPP_DELEGATE_BIND(24, 6, 2, _DPP_DELEGATE_BTDEFS(2, 3, 4), a0, a1, a2, _a0, _a1, a3, a4, a5);
+  _DPP_DELEGATE_BIND(25, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 4), _a0, a0, a1, _a1, _a2, a2, a3, a4);
+  _DPP_DELEGATE_BIND(26, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 4), a0, _a0, a1, _a1, _a2, a2, a3, a4);
+  _DPP_DELEGATE_BIND(27, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 4), _a0, _a1, a0, _a2, _a3, a1, a2, a3);
+  _DPP_DELEGATE_BIND(28, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 4), a0, a1, _a0, _a1, _a2, a2, a3, a4);
+  _DPP_DELEGATE_BIND(29, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 4), _a0, a0, _a1, _a2, _a3, a1, a2, a3);
+  _DPP_DELEGATE_BIND(30, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 4), a0, _a0, _a1, _a2, _a3, a1, a2, a3);
+  _DPP_DELEGATE_BIND(31, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 4), _a0, _a1, _a2, _a3, _a4, a0, a1, a2);
+  _DPP_DELEGATE_BIND(32, 7, 1, _DPP_DELEGATE_BTDEFS(1, 5), a0, a1, a2, a3, a4, _a0, a5, a6);
+  _DPP_DELEGATE_BIND(33, 6, 2, _DPP_DELEGATE_BTDEFS(2, 0, 5), _a0, a0, a1, a2, a3, _a1, a4, a5);
+  _DPP_DELEGATE_BIND(34, 6, 2, _DPP_DELEGATE_BTDEFS(2, 1, 5), a0, _a0, a1, a2, a3, _a1, a4, a5);
+  _DPP_DELEGATE_BIND(35, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 5), _a0, _a1, a0, a1, a2, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(36, 6, 2, _DPP_DELEGATE_BTDEFS(2, 2, 5), a0, a1, _a0, a2, a3, _a1, a4, a5);
+  _DPP_DELEGATE_BIND(37, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 5), _a0, a0, _a1, a1, a2, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(38, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 5), a0, _a0, _a1, a1, a2, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(39, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 5), _a0, _a1, _a2, a0, a1, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(40, 6, 2, _DPP_DELEGATE_BTDEFS(2, 3, 5), a0, a1, a2, _a0, a3, _a1, a4, a5);
+  _DPP_DELEGATE_BIND(41, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 5), _a0, a0, a1, _a1, a2, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(42, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 5), a0, _a0, a1, _a1, a2, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(43, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 5), _a0, _a1, a0, _a2, a1, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(44, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 5), a0, a1, _a0, _a1, a2, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(45, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 5), _a0, a0, _a1, _a2, a1, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(46, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 5), a0, _a0, _a1, _a2, a1, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(47, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 5), _a0, _a1, _a2, _a3, a0, _a4, a1, a2);
+  _DPP_DELEGATE_BIND(48, 6, 2, _DPP_DELEGATE_BTDEFS(2, 4, 5), a0, a1, a2, a3, _a0, _a1, a4, a5);
+  _DPP_DELEGATE_BIND(49, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 4, 5), _a0, a0, a1, a2, _a1, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(50, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 4, 5), a0, _a0, a1, a2, _a1, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(51, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 4, 5), _a0, _a1, a0, a1, _a2, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(52, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 4, 5), a0, a1, _a0, a2, _a1, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(53, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 4, 5), _a0, a0, _a1, a1, _a2, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(54, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 4, 5), a0, _a0, _a1, a1, _a2, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(55, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 4, 5), _a0, _a1, _a2, a0, _a3, _a4, a1, a2);
+  _DPP_DELEGATE_BIND(56, 5, 3, _DPP_DELEGATE_BTDEFS(3, 3, 4, 5), a0, a1, a2, _a0, _a1, _a2, a3, a4);
+  _DPP_DELEGATE_BIND(57, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 4, 5), _a0, a0, a1, _a1, _a2, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(58, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 4, 5), a0, _a0, a1, _a1, _a2, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(59, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 4, 5), _a0, _a1, a0, _a2, _a3, _a4, a1, a2);
+  _DPP_DELEGATE_BIND(60, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 4, 5), a0, a1, _a0, _a1, _a2, _a3, a2, a3);
+  _DPP_DELEGATE_BIND(61, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 4, 5), _a0, a0, _a1, _a2, _a3, _a4, a1, a2);
+  _DPP_DELEGATE_BIND(62, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 4, 5), a0, _a0, _a1, _a2, _a3, _a4, a1, a2);
+  _DPP_DELEGATE_BIND(63, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 4, 5), _a0, _a1, _a2, _a3, _a4, _a5, a0, a1);
+  _DPP_DELEGATE_BIND(64, 7, 1, _DPP_DELEGATE_BTDEFS(1, 6), a0, a1, a2, a3, a4, a5, _a0, a6);
+  _DPP_DELEGATE_BIND(65, 6, 2, _DPP_DELEGATE_BTDEFS(2, 0, 6), _a0, a0, a1, a2, a3, a4, _a1, a5);
+  _DPP_DELEGATE_BIND(66, 6, 2, _DPP_DELEGATE_BTDEFS(2, 1, 6), a0, _a0, a1, a2, a3, a4, _a1, a5);
+  _DPP_DELEGATE_BIND(67, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 6), _a0, _a1, a0, a1, a2, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(68, 6, 2, _DPP_DELEGATE_BTDEFS(2, 2, 6), a0, a1, _a0, a2, a3, a4, _a1, a5);
+  _DPP_DELEGATE_BIND(69, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 6), _a0, a0, _a1, a1, a2, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(70, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 6), a0, _a0, _a1, a1, a2, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(71, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 6), _a0, _a1, _a2, a0, a1, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(72, 6, 2, _DPP_DELEGATE_BTDEFS(2, 3, 6), a0, a1, a2, _a0, a3, a4, _a1, a5);
+  _DPP_DELEGATE_BIND(73, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 6), _a0, a0, a1, _a1, a2, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(74, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 6), a0, _a0, a1, _a1, a2, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(75, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 6), _a0, _a1, a0, _a2, a1, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(76, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 6), a0, a1, _a0, _a1, a2, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(77, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 6), _a0, a0, _a1, _a2, a1, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(78, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 6), a0, _a0, _a1, _a2, a1, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(79, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 6), _a0, _a1, _a2, _a3, a0, a1, _a4, a2);
+  _DPP_DELEGATE_BIND(80, 6, 2, _DPP_DELEGATE_BTDEFS(2, 4, 6), a0, a1, a2, a3, _a0, a4, _a1, a5);
+  _DPP_DELEGATE_BIND(81, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 4, 6), _a0, a0, a1, a2, _a1, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(82, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 4, 6), a0, _a0, a1, a2, _a1, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(83, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 4, 6), _a0, _a1, a0, a1, _a2, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(84, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 4, 6), a0, a1, _a0, a2, _a1, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(85, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 4, 6), _a0, a0, _a1, a1, _a2, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(86, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 4, 6), a0, _a0, _a1, a1, _a2, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(87, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 4, 6), _a0, _a1, _a2, a0, _a3, a1, _a4, a2);
+  _DPP_DELEGATE_BIND(88, 5, 3, _DPP_DELEGATE_BTDEFS(3, 3, 4, 6), a0, a1, a2, _a0, _a1, a3, _a2, a4);
+  _DPP_DELEGATE_BIND(89, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 4, 6), _a0, a0, a1, _a1, _a2, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(90, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 4, 6), a0, _a0, a1, _a1, _a2, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(91, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 4, 6), _a0, _a1, a0, _a2, _a3, a1, _a4, a2);
+  _DPP_DELEGATE_BIND(92, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 4, 6), a0, a1, _a0, _a1, _a2, a2, _a3, a3);
+  _DPP_DELEGATE_BIND(93, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 4, 6), _a0, a0, _a1, _a2, _a3, a1, _a4, a2);
+  _DPP_DELEGATE_BIND(94, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 4, 6), a0, _a0, _a1, _a2, _a3, a1, _a4, a2);
+  _DPP_DELEGATE_BIND(95, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 4, 6), _a0, _a1, _a2, _a3, _a4, a0, _a5, a1);
+  _DPP_DELEGATE_BIND(96, 6, 2, _DPP_DELEGATE_BTDEFS(2, 5, 6), a0, a1, a2, a3, a4, _a0, _a1, a5);
+  _DPP_DELEGATE_BIND(97, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 5, 6), _a0, a0, a1, a2, a3, _a1, _a2, a4);
+  _DPP_DELEGATE_BIND(98, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 5, 6), a0, _a0, a1, a2, a3, _a1, _a2, a4);
+  _DPP_DELEGATE_BIND(99, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 5, 6), _a0, _a1, a0, a1, a2, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(100, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 5, 6), a0, a1, _a0, a2, a3, _a1, _a2, a4);
+  _DPP_DELEGATE_BIND(101, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 5, 6), _a0, a0, _a1, a1, a2, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(102, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 5, 6), a0, _a0, _a1, a1, a2, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(103, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 5, 6), _a0, _a1, _a2, a0, a1, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(104, 5, 3, _DPP_DELEGATE_BTDEFS(3, 3, 5, 6), a0, a1, a2, _a0, a3, _a1, _a2, a4);
+  _DPP_DELEGATE_BIND(105, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 5, 6), _a0, a0, a1, _a1, a2, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(106, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 5, 6), a0, _a0, a1, _a1, a2, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(107, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 5, 6), _a0, _a1, a0, _a2, a1, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(108, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 5, 6), a0, a1, _a0, _a1, a2, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(109, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 5, 6), _a0, a0, _a1, _a2, a1, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(110, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 5, 6), a0, _a0, _a1, _a2, a1, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(111, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 5, 6), _a0, _a1, _a2, _a3, a0, _a4, _a5, a1);
+  _DPP_DELEGATE_BIND(112, 5, 3, _DPP_DELEGATE_BTDEFS(3, 4, 5, 6), a0, a1, a2, a3, _a0, _a1, _a2, a4);
+  _DPP_DELEGATE_BIND(113, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 4, 5, 6), _a0, a0, a1, a2, _a1, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(114, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 4, 5, 6), a0, _a0, a1, a2, _a1, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(115, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 4, 5, 6), _a0, _a1, a0, a1, _a2, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(116, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 4, 5, 6), a0, a1, _a0, a2, _a1, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(117, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 4, 5, 6), _a0, a0, _a1, a1, _a2, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(118, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 4, 5, 6), a0, _a0, _a1, a1, _a2, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(119, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 4, 5, 6), _a0, _a1, _a2, a0, _a3, _a4, _a5, a1);
+  _DPP_DELEGATE_BIND(120, 4, 4, _DPP_DELEGATE_BTDEFS(4, 3, 4, 5, 6), a0, a1, a2, _a0, _a1, _a2, _a3, a3);
+  _DPP_DELEGATE_BIND(121, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 3, 4, 5, 6), _a0, a0, a1, _a1, _a2, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(122, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 3, 4, 5, 6), a0, _a0, a1, _a1, _a2, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(123, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 3, 4, 5, 6), _a0, _a1, a0, _a2, _a3, _a4, _a5, a1);
+  _DPP_DELEGATE_BIND(124, 3, 5, _DPP_DELEGATE_BTDEFS(5, 2, 3, 4, 5, 6), a0, a1, _a0, _a1, _a2, _a3, _a4, a2);
+  _DPP_DELEGATE_BIND(125, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 2, 3, 4, 5, 6), _a0, a0, _a1, _a2, _a3, _a4, _a5, a1);
+  _DPP_DELEGATE_BIND(126, 2, 6, _DPP_DELEGATE_BTDEFS(6, 1, 2, 3, 4, 5, 6), a0, _a0, _a1, _a2, _a3, _a4, _a5, a1);
+  _DPP_DELEGATE_BIND(127, 1, 7, _DPP_DELEGATE_BTDEFS(7, 0, 1, 2, 3, 4, 5, 6), _a0, _a1, _a2, _a3, _a4, _a5, _a6, a0);
+  _DPP_DELEGATE_BIND(128, 7, 1, _DPP_DELEGATE_BTDEFS(1, 7), a0, a1, a2, a3, a4, a5, a6, _a0);
+  _DPP_DELEGATE_BIND(129, 6, 2, _DPP_DELEGATE_BTDEFS(2, 0, 7), _a0, a0, a1, a2, a3, a4, a5, _a1);
+  _DPP_DELEGATE_BIND(130, 6, 2, _DPP_DELEGATE_BTDEFS(2, 1, 7), a0, _a0, a1, a2, a3, a4, a5, _a1);
+  _DPP_DELEGATE_BIND(131, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 1, 7), _a0, _a1, a0, a1, a2, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(132, 6, 2, _DPP_DELEGATE_BTDEFS(2, 2, 7), a0, a1, _a0, a2, a3, a4, a5, _a1);
+  _DPP_DELEGATE_BIND(133, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 2, 7), _a0, a0, _a1, a1, a2, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(134, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 2, 7), a0, _a0, _a1, a1, a2, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(135, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 2, 7), _a0, _a1, _a2, a0, a1, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(136, 6, 2, _DPP_DELEGATE_BTDEFS(2, 3, 7), a0, a1, a2, _a0, a3, a4, a5, _a1);
+  _DPP_DELEGATE_BIND(137, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 3, 7), _a0, a0, a1, _a1, a2, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(138, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 3, 7), a0, _a0, a1, _a1, a2, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(139, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 3, 7), _a0, _a1, a0, _a2, a1, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(140, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 3, 7), a0, a1, _a0, _a1, a2, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(141, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 3, 7), _a0, a0, _a1, _a2, a1, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(142, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 3, 7), a0, _a0, _a1, _a2, a1, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(143, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 3, 7), _a0, _a1, _a2, _a3, a0, a1, a2, _a4);
+  _DPP_DELEGATE_BIND(144, 6, 2, _DPP_DELEGATE_BTDEFS(2, 4, 7), a0, a1, a2, a3, _a0, a4, a5, _a1);
+  _DPP_DELEGATE_BIND(145, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 4, 7), _a0, a0, a1, a2, _a1, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(146, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 4, 7), a0, _a0, a1, a2, _a1, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(147, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 4, 7), _a0, _a1, a0, a1, _a2, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(148, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 4, 7), a0, a1, _a0, a2, _a1, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(149, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 4, 7), _a0, a0, _a1, a1, _a2, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(150, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 4, 7), a0, _a0, _a1, a1, _a2, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(151, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 4, 7), _a0, _a1, _a2, a0, _a3, a1, a2, _a4);
+  _DPP_DELEGATE_BIND(152, 5, 3, _DPP_DELEGATE_BTDEFS(3, 3, 4, 7), a0, a1, a2, _a0, _a1, a3, a4, _a2);
+  _DPP_DELEGATE_BIND(153, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 4, 7), _a0, a0, a1, _a1, _a2, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(154, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 4, 7), a0, _a0, a1, _a1, _a2, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(155, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 4, 7), _a0, _a1, a0, _a2, _a3, a1, a2, _a4);
+  _DPP_DELEGATE_BIND(156, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 4, 7), a0, a1, _a0, _a1, _a2, a2, a3, _a3);
+  _DPP_DELEGATE_BIND(157, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 4, 7), _a0, a0, _a1, _a2, _a3, a1, a2, _a4);
+  _DPP_DELEGATE_BIND(158, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 4, 7), a0, _a0, _a1, _a2, _a3, a1, a2, _a4);
+  _DPP_DELEGATE_BIND(159, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 4, 7), _a0, _a1, _a2, _a3, _a4, a0, a1, _a5);
+  _DPP_DELEGATE_BIND(160, 6, 2, _DPP_DELEGATE_BTDEFS(2, 5, 7), a0, a1, a2, a3, a4, _a0, a5, _a1);
+  _DPP_DELEGATE_BIND(161, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 5, 7), _a0, a0, a1, a2, a3, _a1, a4, _a2);
+  _DPP_DELEGATE_BIND(162, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 5, 7), a0, _a0, a1, a2, a3, _a1, a4, _a2);
+  _DPP_DELEGATE_BIND(163, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 5, 7), _a0, _a1, a0, a1, a2, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(164, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 5, 7), a0, a1, _a0, a2, a3, _a1, a4, _a2);
+  _DPP_DELEGATE_BIND(165, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 5, 7), _a0, a0, _a1, a1, a2, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(166, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 5, 7), a0, _a0, _a1, a1, a2, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(167, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 5, 7), _a0, _a1, _a2, a0, a1, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(168, 5, 3, _DPP_DELEGATE_BTDEFS(3, 3, 5, 7), a0, a1, a2, _a0, a3, _a1, a4, _a2);
+  _DPP_DELEGATE_BIND(169, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 5, 7), _a0, a0, a1, _a1, a2, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(170, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 5, 7), a0, _a0, a1, _a1, a2, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(171, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 5, 7), _a0, _a1, a0, _a2, a1, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(172, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 5, 7), a0, a1, _a0, _a1, a2, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(173, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 5, 7), _a0, a0, _a1, _a2, a1, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(174, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 5, 7), a0, _a0, _a1, _a2, a1, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(175, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 5, 7), _a0, _a1, _a2, _a3, a0, _a4, a1, _a5);
+  _DPP_DELEGATE_BIND(176, 5, 3, _DPP_DELEGATE_BTDEFS(3, 4, 5, 7), a0, a1, a2, a3, _a0, _a1, a4, _a2);
+  _DPP_DELEGATE_BIND(177, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 4, 5, 7), _a0, a0, a1, a2, _a1, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(178, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 4, 5, 7), a0, _a0, a1, a2, _a1, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(179, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 4, 5, 7), _a0, _a1, a0, a1, _a2, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(180, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 4, 5, 7), a0, a1, _a0, a2, _a1, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(181, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 4, 5, 7), _a0, a0, _a1, a1, _a2, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(182, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 4, 5, 7), a0, _a0, _a1, a1, _a2, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(183, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 4, 5, 7), _a0, _a1, _a2, a0, _a3, _a4, a1, _a5);
+  _DPP_DELEGATE_BIND(184, 4, 4, _DPP_DELEGATE_BTDEFS(4, 3, 4, 5, 7), a0, a1, a2, _a0, _a1, _a2, a3, _a3);
+  _DPP_DELEGATE_BIND(185, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 3, 4, 5, 7), _a0, a0, a1, _a1, _a2, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(186, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 3, 4, 5, 7), a0, _a0, a1, _a1, _a2, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(187, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 3, 4, 5, 7), _a0, _a1, a0, _a2, _a3, _a4, a1, _a5);
+  _DPP_DELEGATE_BIND(188, 3, 5, _DPP_DELEGATE_BTDEFS(5, 2, 3, 4, 5, 7), a0, a1, _a0, _a1, _a2, _a3, a2, _a4);
+  _DPP_DELEGATE_BIND(189, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 2, 3, 4, 5, 7), _a0, a0, _a1, _a2, _a3, _a4, a1, _a5);
+  _DPP_DELEGATE_BIND(190, 2, 6, _DPP_DELEGATE_BTDEFS(6, 1, 2, 3, 4, 5, 7), a0, _a0, _a1, _a2, _a3, _a4, a1, _a5);
+  _DPP_DELEGATE_BIND(191, 1, 7, _DPP_DELEGATE_BTDEFS(7, 0, 1, 2, 3, 4, 5, 7), _a0, _a1, _a2, _a3, _a4, _a5, a0, _a6);
+  _DPP_DELEGATE_BIND(192, 6, 2, _DPP_DELEGATE_BTDEFS(2, 6, 7), a0, a1, a2, a3, a4, a5, _a0, _a1);
+  _DPP_DELEGATE_BIND(193, 5, 3, _DPP_DELEGATE_BTDEFS(3, 0, 6, 7), _a0, a0, a1, a2, a3, a4, _a1, _a2);
+  _DPP_DELEGATE_BIND(194, 5, 3, _DPP_DELEGATE_BTDEFS(3, 1, 6, 7), a0, _a0, a1, a2, a3, a4, _a1, _a2);
+  _DPP_DELEGATE_BIND(195, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 1, 6, 7), _a0, _a1, a0, a1, a2, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(196, 5, 3, _DPP_DELEGATE_BTDEFS(3, 2, 6, 7), a0, a1, _a0, a2, a3, a4, _a1, _a2);
+  _DPP_DELEGATE_BIND(197, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 2, 6, 7), _a0, a0, _a1, a1, a2, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(198, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 2, 6, 7), a0, _a0, _a1, a1, a2, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(199, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 2, 6, 7), _a0, _a1, _a2, a0, a1, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(200, 5, 3, _DPP_DELEGATE_BTDEFS(3, 3, 6, 7), a0, a1, a2, _a0, a3, a4, _a1, _a2);
+  _DPP_DELEGATE_BIND(201, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 3, 6, 7), _a0, a0, a1, _a1, a2, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(202, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 3, 6, 7), a0, _a0, a1, _a1, a2, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(203, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 3, 6, 7), _a0, _a1, a0, _a2, a1, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(204, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 3, 6, 7), a0, a1, _a0, _a1, a2, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(205, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 3, 6, 7), _a0, a0, _a1, _a2, a1, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(206, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 3, 6, 7), a0, _a0, _a1, _a2, a1, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(207, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 3, 6, 7), _a0, _a1, _a2, _a3, a0, a1, _a4, _a5);
+  _DPP_DELEGATE_BIND(208, 5, 3, _DPP_DELEGATE_BTDEFS(3, 4, 6, 7), a0, a1, a2, a3, _a0, a4, _a1, _a2);
+  _DPP_DELEGATE_BIND(209, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 4, 6, 7), _a0, a0, a1, a2, _a1, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(210, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 4, 6, 7), a0, _a0, a1, a2, _a1, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(211, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 4, 6, 7), _a0, _a1, a0, a1, _a2, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(212, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 4, 6, 7), a0, a1, _a0, a2, _a1, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(213, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 4, 6, 7), _a0, a0, _a1, a1, _a2, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(214, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 4, 6, 7), a0, _a0, _a1, a1, _a2, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(215, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 4, 6, 7), _a0, _a1, _a2, a0, _a3, a1, _a4, _a5);
+  _DPP_DELEGATE_BIND(216, 4, 4, _DPP_DELEGATE_BTDEFS(4, 3, 4, 6, 7), a0, a1, a2, _a0, _a1, a3, _a2, _a3);
+  _DPP_DELEGATE_BIND(217, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 3, 4, 6, 7), _a0, a0, a1, _a1, _a2, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(218, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 3, 4, 6, 7), a0, _a0, a1, _a1, _a2, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(219, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 3, 4, 6, 7), _a0, _a1, a0, _a2, _a3, a1, _a4, _a5);
+  _DPP_DELEGATE_BIND(220, 3, 5, _DPP_DELEGATE_BTDEFS(5, 2, 3, 4, 6, 7), a0, a1, _a0, _a1, _a2, a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(221, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 2, 3, 4, 6, 7), _a0, a0, _a1, _a2, _a3, a1, _a4, _a5);
+  _DPP_DELEGATE_BIND(222, 2, 6, _DPP_DELEGATE_BTDEFS(6, 1, 2, 3, 4, 6, 7), a0, _a0, _a1, _a2, _a3, a1, _a4, _a5);
+  _DPP_DELEGATE_BIND(223, 1, 7, _DPP_DELEGATE_BTDEFS(7, 0, 1, 2, 3, 4, 6, 7), _a0, _a1, _a2, _a3, _a4, a0, _a5, _a6);
+  _DPP_DELEGATE_BIND(224, 5, 3, _DPP_DELEGATE_BTDEFS(3, 5, 6, 7), a0, a1, a2, a3, a4, _a0, _a1, _a2);
+  _DPP_DELEGATE_BIND(225, 4, 4, _DPP_DELEGATE_BTDEFS(4, 0, 5, 6, 7), _a0, a0, a1, a2, a3, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(226, 4, 4, _DPP_DELEGATE_BTDEFS(4, 1, 5, 6, 7), a0, _a0, a1, a2, a3, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(227, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 1, 5, 6, 7), _a0, _a1, a0, a1, a2, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(228, 4, 4, _DPP_DELEGATE_BTDEFS(4, 2, 5, 6, 7), a0, a1, _a0, a2, a3, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(229, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 2, 5, 6, 7), _a0, a0, _a1, a1, a2, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(230, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 2, 5, 6, 7), a0, _a0, _a1, a1, a2, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(231, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 2, 5, 6, 7), _a0, _a1, _a2, a0, a1, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(232, 4, 4, _DPP_DELEGATE_BTDEFS(4, 3, 5, 6, 7), a0, a1, a2, _a0, a3, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(233, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 3, 5, 6, 7), _a0, a0, a1, _a1, a2, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(234, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 3, 5, 6, 7), a0, _a0, a1, _a1, a2, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(235, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 3, 5, 6, 7), _a0, _a1, a0, _a2, a1, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(236, 3, 5, _DPP_DELEGATE_BTDEFS(5, 2, 3, 5, 6, 7), a0, a1, _a0, _a1, a2, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(237, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 2, 3, 5, 6, 7), _a0, a0, _a1, _a2, a1, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(238, 2, 6, _DPP_DELEGATE_BTDEFS(6, 1, 2, 3, 5, 6, 7), a0, _a0, _a1, _a2, a1, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(239, 1, 7, _DPP_DELEGATE_BTDEFS(7, 0, 1, 2, 3, 5, 6, 7), _a0, _a1, _a2, _a3, a0, _a4, _a5, _a6);
+  _DPP_DELEGATE_BIND(240, 4, 4, _DPP_DELEGATE_BTDEFS(4, 4, 5, 6, 7), a0, a1, a2, a3, _a0, _a1, _a2, _a3);
+  _DPP_DELEGATE_BIND(241, 3, 5, _DPP_DELEGATE_BTDEFS(5, 0, 4, 5, 6, 7), _a0, a0, a1, a2, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(242, 3, 5, _DPP_DELEGATE_BTDEFS(5, 1, 4, 5, 6, 7), a0, _a0, a1, a2, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(243, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 1, 4, 5, 6, 7), _a0, _a1, a0, a1, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(244, 3, 5, _DPP_DELEGATE_BTDEFS(5, 2, 4, 5, 6, 7), a0, a1, _a0, a2, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(245, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 2, 4, 5, 6, 7), _a0, a0, _a1, a1, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(246, 2, 6, _DPP_DELEGATE_BTDEFS(6, 1, 2, 4, 5, 6, 7), a0, _a0, _a1, a1, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(247, 1, 7, _DPP_DELEGATE_BTDEFS(7, 0, 1, 2, 4, 5, 6, 7), _a0, _a1, _a2, a0, _a3, _a4, _a5, _a6);
+  _DPP_DELEGATE_BIND(248, 3, 5, _DPP_DELEGATE_BTDEFS(5, 3, 4, 5, 6, 7), a0, a1, a2, _a0, _a1, _a2, _a3, _a4);
+  _DPP_DELEGATE_BIND(249, 2, 6, _DPP_DELEGATE_BTDEFS(6, 0, 3, 4, 5, 6, 7), _a0, a0, a1, _a1, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(250, 2, 6, _DPP_DELEGATE_BTDEFS(6, 1, 3, 4, 5, 6, 7), a0, _a0, a1, _a1, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(251, 1, 7, _DPP_DELEGATE_BTDEFS(7, 0, 1, 3, 4, 5, 6, 7), _a0, _a1, a0, _a2, _a3, _a4, _a5, _a6);
+  _DPP_DELEGATE_BIND(252, 2, 6, _DPP_DELEGATE_BTDEFS(6, 2, 3, 4, 5, 6, 7), a0, a1, _a0, _a1, _a2, _a3, _a4, _a5);
+  _DPP_DELEGATE_BIND(253, 1, 7, _DPP_DELEGATE_BTDEFS(7, 0, 2, 3, 4, 5, 6, 7), _a0, a0, _a1, _a2, _a3, _a4, _a5, _a6);
+  _DPP_DELEGATE_BIND(254, 1, 7, _DPP_DELEGATE_BTDEFS(7, 1, 2, 3, 4, 5, 6, 7), a0, _a0, _a1, _a2, _a3, _a4, _a5, _a6);
+  _DPP_DELEGATE_BIND(255, 0, 8, _DPP_DELEGATE_BTDEFS(8, 0, 1, 2, 3, 4, 5, 6, 7), _a0, _a1, _a2, _a3, _a4, _a5, _a6, _a7);
+#endif
+
+#if DPP_DELEGATE_ARGC > 8
+# error DPP_DELEGATE_ARGC > 8 not supported
+#endif
+
+  //////////////////////////////////////////////////////////////////////
+  //	container push delegate class
+  //////////////////////////////////////////////////////////////////////
+
+  template <class X, int id, bool smart, class ItemBase>
+  class linked_list;
+
+  /** @internal */
+  template <class Container>
+  struct delegate_push_types
+  {
+    typedef typename Container::const_reference arg;
+  };
+
+  /** @internal */
+  template <class X, int id, bool smart, class ItemBase>
+  struct delegate_push_types <linked_list<X, id, smart, ItemBase> >
+  {
+    typedef _DPP_DR106(X) & arg;
+  };
+
+  /** @internal */
+  template <class A0, class PushArg>
+  struct delegate_push_ptr
+  {
+    typedef PushArg arg;
+    static _DPP_DR106(PushArg) & get(_DPP_DR106(A0) &a0)
+    {
+      return a0;
+    }
+  };
+
+  /** @internal */
+  template <class A0, class PushArg>
+  struct delegate_push_ptr<A0, PushArg* const &>
+  {
+    typedef PushArg * const & arg;
+    static PushArg * get(_DPP_DR106(A0) &a0)
+    {
+      return &a0;
+    }
+  };
+
+  /**
+     @short Container push delegate class
+     @main
+     @header dpp/delegate
+     @prototype template <typename Container, typename A0 = [...], void (Container::*PushFunc)([...]) = &Container::push_back>
+
+     This delegate class push items on container on invocation.
+
+     @param Container Container type
+     @param A0 Type of single argument of delegate prototype
+     @param PushArg Type of container push function argument
+     @param Push Container push member function, default is @tt push_back
+
+     Usage example:
+     @example test/test_delegate.cc:push|push1
+     Usage with value argument type instead of reference:
+     @example test/test_delegate.cc:push|push2
+     Usage with container @tt push_front function:
+     @example test/test_delegate.cc:push|push3
+     Usage with pointers container:
+     @example test/test_delegate.cc:push4
+  */
+  template <typename Container,
+	    typename A0 = typename delegate_push_types<Container>::arg,
+	    void (Container::*PushFunc)(
+	      typename delegate_push_ptr<A0,
+	        typename delegate_push_types<Container>::arg>::arg
+	    ) = &Container::push_back>
+  class delegate_push
+    : public delegate< void (A0) >
+  {
+  public:
+
+    delegate_push()
+      : _cont(0)
+    {
+    }
+
+    delegate_push(Container &cont)
+      : _cont(&cont)
+    {
+    }
+
+    void operator()(A0 a0) const
+    {
+      return delegate_push::call(a0);
+    }
+
+    bool valid() const
+    {
+      return _cont;
+    }
+
+  private:
+    void call(A0 a0) const
+    {
+      (_cont->*PushFunc)(delegate_push_ptr<A0, typename delegate_push_types<Container>::arg>::get(a0));
+    }
+
+    Container *_cont;
+  };
+
+//////////////////////////////////////////////////////////////////////
+//	container iterator delegate class
+//////////////////////////////////////////////////////////////////////
+
+/** @internal */
+template <class C> struct delegate_iterate_types
+{
+  typedef typename C::iterator iterator;
+  typedef typename C::value_type & reference;
+};
+
+/** @internal */
+template <class C> struct delegate_iterate_types <const C>
+{
+  typedef typename C::const_iterator iterator;
+  typedef const typename C::value_type & reference;
+};
+
+/**
+   @short Container traversal delegate class
+   @main
+   @header dpp/delegate
+
+   This delegate class can be used to returns each item present in
+   associated container.
+
+   @param Container Container type
+   @param R Return type of delegate prototype
+
+   Usage example:
+   @example test/test_delegate.cc:push|iter1
+*/
+template <typename Container,
+	  typename R = typename delegate_iterate_types<Container>::reference>
+class delegate_iterate
+  : public delegate< R () >
+{
+public:
+
+  typedef typename delegate_iterate_types<Container>::iterator iterator;
+
+  delegate_iterate(Container &cont)
+    : _i(cont.begin()),
+      _end(cont.end())
+  {
+  }
+
+  delegate_iterate(const iterator &begin, const iterator &end)
+    : _i(begin),
+      _end(end)
+  {
+  }
+
+  /** Test if container end has been reached. */
+  bool valid() const
+  {
+    return _i != _end;
+  }
+
+  R operator()() const
+  {
+    return delegate_iterate::call();
+  }
+
+private:
+  R call() const
+  {
+    delegate_iterate *_this = const_cast<delegate_iterate*>(this);
+    return *_this->_i++;
+  }
+
+  iterator _i;
+  iterator _end;
+};
+
+//////////////////////////////////////////////////////////////////////
+//	container output delegate class
+//////////////////////////////////////////////////////////////////////
+
+/**
+   @short Standard stream output delegate class
+   @main
+   @header dpp/delegate
+
+   This delegate class can be used to write to a @ref std::ostream
+   stream on invocation.
+
+   A separator string which is output after each value may be
+   specified.
+
+   @param Container Container type
+   @param A0 Type of single argument of delegate prototype
+
+   Usage example:
+   @example test/test_delegate.cc:ostream
+*/
+template <typename A0>
+class delegate_ostream
+  : public delegate< void (A0) >
+{
+public:
+
+  delegate_ostream()
+    : _out(0)
+  {
+  }
+
+  delegate_ostream(std::ostream &out, const char *sep = "")
+    : _out(&out),
+      _sep(sep)
+  {
+  }
+
+  /** @This returns @ref std::ostream::good function result on stream. */
+  bool valid() const
+  {
+    return _out && _out->good();
+  }
+
+  void operator()(A0 a0) const
+  {
+    return delegate_ostream::call(a0);
+  }
+
+private:
+  void call(A0 a0) const
+  {
+    *_out << a0 << _sep;
+  }
+
+  std::ostream *_out;
+  const char *_sep;
+};
+
+
+//////////////////////////////////////////////////////////////////////
+//	container input delegate class
+//////////////////////////////////////////////////////////////////////
+
+/**
+   @short Standard stream input delegate class
+   @main
+   @header dpp/delegate
+
+   This delegate class can be used to read from a @ref std::istream
+   stream on invocation.
+
+   Usage example:
+   @example test/test_delegate.cc:istream
+*/
+template <typename R>
+class delegate_istream
+  : public delegate< R () >
+{
+public:
+
+  delegate_istream(std::istream &in)
+    : _in(&in)
+  {
+  }
+
+  /** @This returns @ref std::istream::good function result on stream. */
+  bool valid() const
+  {
+    return _in && _in->good();
+  }
+
+  R operator()() const
+  {
+    return delegate_istream::call();
+  }
+
+private:
+  R call() const
+  {
+    R r;
+    *_in >> r;
+    return r;
+  }
+
+  std::istream *_in;
+};
+
+
+//////////////////////////////////////////////////////////////////////
+//	user delegate class definition macros
+//////////////////////////////////////////////////////////////////////
+
+#define _DPP_DELEGATE_X(a, b) a##b
+#define _DPP_DELEGATE_NAME(l) _DPP_DELEGATE_X(_my_delegate, l)
+
+/** @This provides a convenient way to write custom delegate types.
+    @see {#DPP_DELEGATE0_OBJ, #DPP_DELEGATE1_TYPE}
+
+    @example test/test_delegate.cc:my0
+    @showcontent
+ */
+#define DPP_DELEGATE0_TYPE(return_type, args_list, ...)	\
+  class : public dpp::delegate< return_type args_list >	\
+  {							\
+    bool valid() const					\
+    {							\
+      return true;					\
+    }							\
+							\
+    return_type call args_list const			\
+    {							\
+      __VA_ARGS__;					\
+    }							\
+  }
+
+/** @see {#DPP_DELEGATE0_TYPE} @showcontent */
+# define DPP_DELEGATE0_OBJ(name, return_type, args_list, ...) \
+  DPP_DELEGATE0_TYPE(return_type, args_list, __VA_ARGS__) name
+
+#if DPP_DELEGATE_ARGC >= 1
+
+/** @see {#DPP_DELEGATE1_OBJ, #DPP_DELEGATE0_TYPE} @showcontent */
+# define DPP_DELEGATE1_TYPE(return_type, args_list, data0_type, ...)	\
+  class _DPP_DELEGATE_NAME(__LINE__)					\
+    : public dpp::delegate< return_type args_list >			\
+  {									\
+  public:								\
+    _DPP_DELEGATE_NAME(__LINE__)(data0_type data0)			\
+      : _0(data0)							\
+    {}									\
+  private:								\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    return_type call args_list const					\
+    {									\
+      __VA_ARGS__;							\
+    }									\
+									\
+    data0_type _0;							\
+  }
+
+/** @This provides a convenient way to create custom delegate
+    objects.
+
+    One or more data fields can be embedded in delegate object by
+    using one of the @tt DPP_DELEGATEn_OBJ macros:
+
+    @example test/test_delegate.cc:my1
+    @showcontent
+
+    @see {#DPP_DELEGATE1_TYPE, #DPP_DELEGATEO_OBJ,
+    #DPP_DELEGATE2_OBJ, #DPP_DELEGATE3_OBJ, #DPP_DELEGATE4_OBJ}
+*/
+# define DPP_DELEGATE1_OBJ(name, return_type, args_list, data0_type, init0, ...) \
+  DPP_DELEGATE1_TYPE(return_type, args_list, data0_type, __VA_ARGS__)	\
+  name(init0)
+
+#endif
+
+#if DPP_DELEGATE_ARGC >= 2
+
+/** @see {#DPP_DELEGATE2_OBJ, #DPP_DELEGATE1_TYPE} */
+# define DPP_DELEGATE2_TYPE(return_type, args_list, data0_type, data1_type, ...) \
+  class _DPP_DELEGATE_NAME(__LINE__)					\
+    : public dpp::delegate< return_type args_list >			\
+  {									\
+  public:								\
+    _DPP_DELEGATE_NAME(__LINE__)(data0_type data0, data1_type data1)	\
+      : _0(data0), _1(data1)						\
+    {}									\
+  private:								\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    return_type call args_list const					\
+    {									\
+      __VA_ARGS__;							\
+    }									\
+									\
+    data0_type _0;							\
+    data1_type _1;							\
+  }
+
+/** @see {#DPP_DELEGATE2_TYPE, #DPP_DELEGATE1_OBJ} */
+# define DPP_DELEGATE2_OBJ(name, return_type, args_list, data0_type, init0, data1_type, init1, ...) \
+  DPP_DELEGATE2_TYPE(return_type, args_list, data0_type, data1_type, __VA_ARGS__) \
+  name(init0, init1)
+
+#endif
+
+#if DPP_DELEGATE_ARGC >= 3
+
+/** @see {#DPP_DELEGATE3_OBJ, #DPP_DELEGATE1_TYPE} */
+# define DPP_DELEGATE3_TYPE(return_type, args_list, data0_type, data1_type, data2_type, ...) \
+  class _DPP_DELEGATE_NAME(__LINE__)					\
+    : public dpp::delegate< return_type args_list >			\
+  {									\
+  public:								\
+    _DPP_DELEGATE_NAME(__LINE__)(data0_type data0, data1_type data1, data2_type data2) \
+      : _0(data0), _1(data1), _2(data2)					\
+    {}									\
+  private:								\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    return_type call args_list const					\
+    {									\
+      __VA_ARGS__;							\
+    }									\
+									\
+    data0_type _0;							\
+    data1_type _1;							\
+    data2_type _2;							\
+  }
+
+/** @see {#DPP_DELEGATE3_TYPE, #DPP_DELEGATE1_OBJ} */
+# define DPP_DELEGATE3_OBJ(name, return_type, args_list, data0_type, init0, data1_type, init1, data2_type, init2, ...)  \
+  DPP_DELEGATE3_TYPE(return_type, args_list, data0_type, data1_type, data2_type, __VA_ARGS__)  \
+    name(init0, init1, init2)
+
+#endif
+
+#if DPP_DELEGATE_ARGC >= 4
+
+/** @see {#DPP_DELEGATE4_OBJ, #DPP_DELEGATE1_TYPE} */
+# define DPP_DELEGATE4_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, ...) \
+  class _DPP_DELEGATE_NAME(__LINE__)					\
+    : public dpp::delegate< return_type args_list >			\
+  {									\
+  public:								\
+    _DPP_DELEGATE_NAME(__LINE__)(data0_type data0, data1_type data1, data2_type data2, data3_type data3) \
+      : _0(data0), _1(data1), _2(data2), _3(data3)			\
+    {}									\
+  private:								\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    return_type call args_list const					\
+    {									\
+      __VA_ARGS__;							\
+    }									\
+									\
+    data0_type _0;							\
+    data1_type _1;							\
+    data2_type _2;							\
+    data3_type _3;							\
+  }
+
+/** @see {#DPP_DELEGATE4_TYPE, #DPP_DELEGATE1_OBJ} */
+# define DPP_DELEGATE4_OBJ(name, return_type, args_list, data0_type, init0, data1_type, init1, data2_type, init2, data3_type, init3, ...)  \
+  DPP_DELEGATE4_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, __VA_ARGS__)  \
+    name(init0, init1, init2, init3)
+
+#endif
+
+#if DPP_DELEGATE_ARGC >= 5 // mkdoc:skip
+
+/** @see {#DPP_DELEGATE5_OBJ, #DPP_DELEGATE1_TYPE} */
+# define DPP_DELEGATE5_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, data4_type, ...) \
+  class _DPP_DELEGATE_NAME(__LINE__)					\
+    : public dpp::delegate< return_type args_list >			\
+  {									\
+  public:								\
+    _DPP_DELEGATE_NAME(__LINE__)(data0_type data0, data1_type data1, data2_type data2, data3_type data3, data4_type data4) \
+      : _0(data0), _1(data1), _2(data2), _3(data3), _4(data4)		\
+    {}									\
+  private:								\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    return_type call args_list const					\
+    {									\
+      __VA_ARGS__;							\
+    }									\
+									\
+    data0_type _0;							\
+    data1_type _1;							\
+    data2_type _2;							\
+    data3_type _3;							\
+    data4_type _4;							\
+  }
+
+/** @see {#DPP_DELEGATE5_TYPE, #DPP_DELEGATE1_OBJ} */
+# define DPP_DELEGATE5_OBJ(name, return_type, args_list, data0_type, init0, data1_type, init1, data2_type, init2, data3_type, init3, data4_type, init4, ...)  \
+  DPP_DELEGATE5_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, data4_type, __VA_ARGS__)  \
+    name(init0, init1, init2, init3, init4)
+
+#endif
+
+#if DPP_DELEGATE_ARGC >= 6 // mkdoc:skip
+
+/** @see {#DPP_DELEGATE6_OBJ, #DPP_DELEGATE1_TYPE} */
+# define DPP_DELEGATE6_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, data4_type, data5_type, ...) \
+  class _DPP_DELEGATE_NAME(__LINE__)					\
+    : public dpp::delegate< return_type args_list >			\
+  {									\
+  public:								\
+    _DPP_DELEGATE_NAME(__LINE__)(data0_type data0, data1_type data1, data2_type data2, data3_type data3, data4_type data4, data5_type data5) \
+      : _0(data0), _1(data1), _2(data2), _3(data3), _4(data4), _5(data5) \
+    {}									\
+  private:								\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    return_type call args_list const					\
+    {									\
+      __VA_ARGS__;							\
+    }									\
+									\
+    data0_type _0;							\
+    data1_type _1;							\
+    data2_type _2;							\
+    data3_type _3;							\
+    data4_type _4;							\
+    data5_type _5;							\
+  }
+
+/** @see {#DPP_DELEGATE6_TYPE, #DPP_DELEGATE1_OBJ} */
+# define DPP_DELEGATE6_OBJ(name, return_type, args_list, data0_type, init0, data1_type, init1, data2_type, init2, data3_type, init3, data4_type, init4, data5_type, init5, ...)  \
+  DPP_DELEGATE6_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, data4_type, data5_type, __VA_ARGS__)  \
+    name(init0, init1, init2, init3, init4, init5)
+
+#endif
+
+#if DPP_DELEGATE_ARGC >= 7 // mkdoc:skip
+
+/** @see {#DPP_DELEGATE7_OBJ, #DPP_DELEGATE1_TYPE} */
+# define DPP_DELEGATE7_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, data4_type, data5_type, data6_type, ...) \
+  class _DPP_DELEGATE_NAME(__LINE__)					\
+    : public dpp::delegate< return_type args_list >			\
+  {									\
+  public:								\
+    _DPP_DELEGATE_NAME(__LINE__)(data0_type data0, data1_type data1, data2_type data2, data3_type data3, data4_type data4, data5_type data5, data6_type data6) \
+      : _0(data0), _1(data1), _2(data2), _3(data3), _4(data4), _5(data5), _6(data6) \
+    {}									\
+  private:								\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    return_type call args_list const					\
+    {									\
+      __VA_ARGS__;							\
+    }									\
+									\
+    data0_type _0;							\
+    data1_type _1;							\
+    data2_type _2;							\
+    data3_type _3;							\
+    data4_type _4;							\
+    data5_type _5;							\
+    data6_type _6;							\
+  }
+
+/** @see {#DPP_DELEGATE7_TYPE, #DPP_DELEGATE1_OBJ} */
+# define DPP_DELEGATE7_OBJ(name, return_type, args_list, data0_type, init0, data1_type, init1, data2_type, init2, data3_type, init3, data4_type, init4, data5_type, init5, data6_type, init6, ...)  \
+  DPP_DELEGATE7_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, data4_type, data5_type, data6_type, __VA_ARGS__)  \
+    name(init0, init1, init2, init3, init4, init5, init6)
+
+#endif
+
+#if DPP_DELEGATE_ARGC >= 8 // mkdoc:skip
+
+/** @see {#DPP_DELEGATE8_OBJ, #DPP_DELEGATE1_TYPE} */
+# define DPP_DELEGATE8_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, data4_type, data5_type, data6_type, data7_type, ...) \
+  class _DPP_DELEGATE_NAME(__LINE__)					\
+    : public dpp::delegate< return_type args_list >			\
+  {									\
+  public:								\
+    _DPP_DELEGATE_NAME(__LINE__)(data0_type data0, data1_type data1, data2_type data2, data3_type data3, data4_type data4, data5_type data5, data6_type data6, data7_type data7) \
+      : _0(data0), _1(data1), _2(data2), _3(data3), _4(data4), _5(data5), _6(data6), _7(data7) \
+    {}									\
+  private:								\
+    bool valid() const							\
+    {									\
+      return true;							\
+    }									\
+									\
+    return_type call args_list const					\
+    {									\
+      __VA_ARGS__;							\
+    }									\
+									\
+    data0_type _0;							\
+    data1_type _1;							\
+    data2_type _2;							\
+    data3_type _3;							\
+    data4_type _4;							\
+    data5_type _5;							\
+    data6_type _6;							\
+    data7_type _7;							\
+  }
+
+/** @see {#DPP_DELEGATE8_TYPE, #DPP_DELEGATE1_OBJ} */
+# define DPP_DELEGATE8_OBJ(name, return_type, args_list, data0_type, init0, data1_type, init1, data2_type, init2, data3_type, init3, data4_type, init4, data5_type, init5, data6_type, init6, data7_type, init7, ...)  \
+  DPP_DELEGATE8_TYPE(return_type, args_list, data0_type, data1_type, data2_type, data3_type, data4_type, data5_type, data6_type, data7_type, __VA_ARGS__)  \
+    name(init0, init1, init2, init3, init4, init5, init6, init7)
+
+#endif
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/foreach
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/foreach	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/foreach	(revision 283)
@@ -0,0 +1,23 @@
+// -*- c++ -*-
+
+#ifndef DPP_FOREACH_HH_
+#define DPP_FOREACH_HH_
+
+#ifdef __GNUC__
+
+#define FOREACH(var, cont)			\
+  for (typeof((cont).begin()) var = (cont).begin(); \
+       var !=(cont).end(); \
+       ++var)
+
+// this version prefetch next item to allow current item deletion on some container
+#define FOREACH2(var, cont)			\
+  for (typeof((cont).begin()) var##__next = (cont).begin(), var; \
+       (var = var##__next++) !=(cont).end(); )
+
+#else
+# error typeof not available
+#endif
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/fstring
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/fstring	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/fstring	(revision 283)
@@ -0,0 +1,235 @@
+/* -*- c++ -*-
+
+   Formatted string class
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2008-2011 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_FSTRING_HH_
+#define DPP_FSTRING_HH_
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <string>
+
+/** @file @module{Formatted string} */
+
+#ifdef __GNUC__
+# define _DPP_FORMAT_CHK(archetype, string_index, first_to_check)
+#else
+# define _DPP_FORMAT_CHK(archetype, string_index, first_to_check) \
+  __attribute__((format(archetype, string_index, first_to_check)))
+#endif
+
+namespace dpp {
+
+  /**
+     @short Extended std::string with sprintf family of functions.
+     @module {Formatted string}
+     @header dpp/fstring
+     @main
+
+     This class provides an extension of the @ref std::string class
+     with @ref sprintf family of functions and constructors,
+     for those who find @ref std::ostringstream sometimes cumbersome
+     to use. Yes, I know, it's not type safe.
+
+     Allocation is performed by underlying @ref std::string class and
+     format string are processed using the @ref ::vsnprintf libc function
+     with proper buffer size.
+   */
+  class fstring : public std::string
+  {
+  public:
+    /** @multiple @ref std::string standard constructor */
+    fstring()
+      : std::string()
+    {
+    }
+
+    explicit fstring(const std::string &str)
+      : std::string(str)
+    {
+    }
+
+    /** @This creates a @ref fstring object from char array. Unlike
+	the @insert {__fstring2__} prototype constructor, @this does
+	not perform formatting; initialization with buffer containing
+	conversion specifiers is safe to use. */
+    fstring(const char *str)
+      : std::string(str)
+    {
+    }
+
+#ifdef __MKDOC__
+    /** @This creates a @ref fstring object from format string and
+	associated arguments. Up to 16 extra arguments can be passed.
+	@alias fstring2
+    */
+    fstring(const char *str, ...);
+
+#else // mkdoc:skip
+
+#define _DPP_FSTRING_CSTR(b, c, ...)					\
+    _DPP_FORMAT_CHK(printf, 1, 2)					\
+    template <__VA_ARGS__>						\
+    fstring b								\
+    {									\
+      dpp::fstring::sprintf c;						\
+    }
+
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0),
+       (fmt, a0),
+       typename A0)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1),
+       (fmt, a0, a1),
+       typename A0, typename A1)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2),
+       (fmt, a0, a1, a2),
+       typename A0, typename A1, typename A2)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3),
+       (fmt, a0, a1, a2, a3),
+       typename A0, typename A1, typename A2, typename A3)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4),
+       (fmt, a0, a1, a2, a3, a4),
+       typename A0, typename A1, typename A2, typename A3, typename A4)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5),
+       (fmt, a0, a1, a2, a3, a4, a5),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6),
+       (fmt, a0, a1, a2, a3, a4, a5, a6),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10, const A11 &a11),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10, const A11 &a11, const A12 &a12),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10, const A11 &a11, const A12 &a12, const A13 &a13),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10, const A11 &a11, const A12 &a12, const A13 &a13, const A14 &a14),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename A14)
+    _DPP_FSTRING_CSTR((const char *fmt, const A0 &a0, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9, const A10 &a10, const A11 &a11, const A12 &a12, const A13 &a13, const A14 &a14, const A15 &a15),
+       (fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15),
+       typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename A14, typename A15)
+#endif
+
+    /** @This preallocates a string of given size and creates a @ref
+	fstring from format string and associated arguments. */
+    _DPP_FORMAT_CHK(printf, 1, 3)
+    fstring(size_t size, const char *fmt, ...)
+    {
+      va_list ap;
+      va_start(ap, fmt);
+      dpp::fstring::vsnprintf(size, fmt, ap);
+      va_end(ap);
+    }
+
+    /** @This overwrites current content using format string and
+	associated arguments. */
+    int vsprintf(const char *fmt, va_list ap)
+    {
+      int s;
+      va_list aq;
+
+      va_copy(aq, ap);
+      if (empty())
+        s = ::vsnprintf(NULL, 0, fmt, aq);
+      else
+        s = ::vsnprintf(&at(0), size() + 1, fmt, aq);
+
+      if (s >= 0 && s > (int)size())
+	{
+	  resize(s);
+	  s = ::vsnprintf(&at(0), size() + 1, fmt, ap);
+	}
+
+      va_end(aq);
+      return s;
+    }
+
+    /** @This resizes current buffer and overwrite its content
+	using format string and associated arguments. */
+    int vsnprintf(size_t size, const char *fmt, va_list ap)
+    {
+      resize(size);
+      return ::vsnprintf(&at(0), size + 1, fmt, ap);
+    }
+
+    /** @This overwrites current content using format string and
+	associated arguments. */
+    _DPP_FORMAT_CHK(printf, 1, 2)
+    int sprintf(const char *fmt, ...)
+    {
+      va_list ap;
+      int res;
+      va_start(ap, fmt);
+      res = dpp::fstring::vsprintf(fmt, ap);
+      va_end(ap);
+      return res;
+    }
+
+    /** @This resizes current buffer and overwrite its content
+	using format string and associated arguments. */
+    _DPP_FORMAT_CHK(printf, 1, 3)
+    int snprintf(size_t size, const char *fmt, ...)
+    {
+      va_list ap;
+      int res;
+      va_start(ap, fmt);
+      res = dpp::fstring::vsnprintf(size, fmt, ap);
+      va_end(ap);
+      return res;
+    }
+
+    /** @This returns the buffer content as a @tt{const char *}. @see c_str */
+    operator const char *() {
+      return c_str();
+    }
+
+    /** @This returns the buffer content as a @tt{const char *}. @see c_str */
+    const char * operator+() {
+      return c_str();
+    }
+
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/interval_set
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/interval_set	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/interval_set	(revision 283)
@@ -0,0 +1,852 @@
+/* -*- c++ -*-
+
+   C++ Interval set template with boolean operations.
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2008 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_INTERVAL_SET_HH_
+#define DPP_INTERVAL_SET_HH_
+
+#include <cassert>
+#include <vector>
+#include <stdexcept>
+#include <limits>
+#include <ios>
+
+/** @file @module{Interval set} */
+
+namespace dpp {
+
+  template <typename X>
+  class interval_bound;
+
+  template <typename X>
+  class interval_bound_inclusive;
+
+  template <typename X>
+  class interval_bound_exclusive;
+
+  template <typename X>
+  class interval_scalar_limits;
+
+  template <typename X, class Bound = interval_bound<X> >
+  class interval;
+
+  template <typename X, class Bound = interval_bound<X>,
+	    class Limits = interval_scalar_limits<X> >
+  class interval_set;
+
+//////////////////////////////////////////////////////////////////////
+//	interval bound classes
+//////////////////////////////////////////////////////////////////////
+
+  /** @short Default interval bound class
+      @module {Interval set}
+      @header dpp/interval_set
+
+      @This may be used with the @ref interval and @ref interval_set
+      classes to specify interval bounds inclusivity.
+
+      This class must be used to handles both inclusive and exclusive
+      interval bounds in the same interval set. This is the default
+      behavior and more generic choice but @ref interval_bound_inclusive
+      and @ref interval_bound_exclusive may be used instead to allow
+      further optimization of the code.
+  */
+
+  template <typename X>
+  class interval_bound
+  {
+    template <typename, class> friend class interval;
+    template <typename, class, class> friend class interval_set;
+
+    X _bound;
+    bool _inclusive;
+
+    interval_bound()
+    {
+    }
+
+    interval_bound(const X bound, bool inclusive)
+      : _bound(bound),
+	_inclusive(inclusive)
+    {
+    }
+
+    X bound() const
+    {
+      return _bound;
+    }
+
+    void set_bound(X b)
+    {
+      _bound = b;
+    }
+
+    bool inclusive() const
+    {
+      return _inclusive;
+    }
+
+    void set_inclusive(bool i)
+    {
+      _inclusive = i;
+    }
+
+    bool operator==(const interval_bound &b) const
+    {
+      return _bound == b._bound && _inclusive == b._inclusive;
+    }
+
+    static const bool default_inc = true;
+  };
+
+  /** @short Inclusive interval bound class
+      @module {Interval set}
+      @header dpp/interval_set
+
+      @This may be used with the @ref interval and @ref interval_set
+      classes to specify interval bounds inclusivity.
+
+      When used this specify @b inclusive bounds and @ref interval bound values 
+      will always be considered as included in the interval.
+
+      @see interval_bound
+      @see interval_bound_exclusive
+  */
+
+  template <typename X>
+  class interval_bound_inclusive
+  {
+    template <typename, class> friend class interval;
+    template <typename, class, class> friend class interval_set;
+
+    X _bound;
+
+    interval_bound_inclusive()
+    {
+    }
+
+    interval_bound_inclusive(const X bound, bool inclusive)
+      : _bound(bound)
+    {
+    }
+
+    X bound() const
+    {
+      return _bound;
+    }
+
+    void set_bound(X b)
+    {
+      _bound = b;
+    }
+
+    bool inclusive() const
+    {
+      return true;
+    }
+
+    void set_inclusive(bool i)
+    {
+      assert(i);
+    }
+
+    bool operator==(const interval_bound_inclusive &b) const
+    {
+      return _bound == b._bound;
+    }
+
+    static const bool default_inc = true;
+  };
+
+  /** @short Exclusive interval bound class
+      @module {Interval set}
+      @header dpp/interval_set
+
+      @This may be used with the @ref interval and @ref interval_set
+      classes to specify interval bounds inclusivity.
+
+      When used this specify @b exclusive bounds and @ref interval bound values
+      will always be considered as excluded from the interval.
+
+      @see interval_bound
+      @see interval_bound_inclusive
+  */
+
+  template <typename X>
+  class interval_bound_exclusive
+  {
+    template <typename, class> friend class interval;
+    template <typename, class, class> friend class interval_set;
+
+    X _bound;
+
+    interval_bound_exclusive()
+    {
+    }
+
+    interval_bound_exclusive(X bound, bool inclusive)
+      : _bound(bound)
+    {
+    }
+
+    X bound() const
+    {
+      return _bound;
+    }
+
+    void set_bound(X b)
+    {
+      _bound = b;
+    }
+
+    bool inclusive() const
+    {
+      return false;
+    }
+
+    void set_inclusive(bool i)
+    {
+      assert(!i);
+    }
+
+    bool operator==(const interval_bound_exclusive &b) const
+    {
+      return _bound == b._bound;
+    }
+
+    static const bool default_inc = false;
+  };
+
+//////////////////////////////////////////////////////////////////////
+//	interval bound limits
+//////////////////////////////////////////////////////////////////////
+
+  /** @short Interval limits class for standard scalar types
+      @module {Interval set}
+      @header dpp/interval_set
+
+      This class specify upper and lower limits for scalar types and
+      is the default limits definition class used by the @ref interval_set class.
+
+      Similar classes must be defined when using the @ref interval_set
+      class with user defined non scalar types.
+  */
+
+  template <typename X>
+  class interval_scalar_limits
+  {
+  public:
+    /** @This returns interval maximum value */
+    static X upper()
+    {
+      if (!std::numeric_limits<X>::is_integer && std::numeric_limits<X>::has_infinity)
+	return std::numeric_limits<X>::infinity();
+      else
+	return std::numeric_limits<X>::max();
+    }
+
+    /** @This returns interval minimum value */
+    static X lower()
+    {
+      if (std::numeric_limits<X>::is_integer)
+	return std::numeric_limits<X>::min();
+      else
+	return -upper();
+    }
+  };
+
+//////////////////////////////////////////////////////////////////////
+//	interval (bound pair) class
+//////////////////////////////////////////////////////////////////////
+
+  /** @short Interval class
+      @module {Interval set}
+      @header dpp/interval_set
+      @main
+      @showvalue
+
+      @This defines an interval with its low and high bounds for a
+      given type and bound inclusivity.
+
+      @tt X can be a standard scalar type or an user defined type.
+
+      Acceptable values for @tt Bound template parameter are
+      @ref interval_bound (default), @ref interval_bound_inclusive and
+      @ref interval_bound_exclusive
+
+      This class is used as an @ref interval_set element.
+  */
+
+  template <typename X, class Bound>
+  class interval
+  {
+    template <typename, class, class> friend class interval_set;
+
+    Bound _low;
+    Bound _high;
+
+  public:
+
+    /** @This creates a non initialized interval object. */
+    interval()
+    {
+    }
+
+    /** @This creates a new {@tt low, @tt high } interval.
+	Bounds are inclusive by default when @ref interval_bound_exclusive is not used.
+	@alias interval_1
+    */
+    interval(const X low, const X high)
+      : _low(low, Bound::default_inc),
+	_high(high, Bound::default_inc)
+    {
+      assert(low < high || low == high);
+    }
+
+    /** @This creates a new {@tt low, @tt high } interval with specified inclusivity.
+	@alias interval_2
+     */
+    interval(const X low, bool low_inclusive,
+	     const X high, bool high_inclusive)
+      : _low(low, low_inclusive),
+	_high(high, high_inclusive)	
+    {
+      assert(low < high || (low == high && low_inclusive && high_inclusive));
+    }
+
+    /** @This returns the low bound value. */
+    X low_bound() const
+    {
+      return _low.bound();
+    }
+
+    /** @This returns the high bound value. */
+    X high_bound() const
+    {
+      return _high.bound();
+    }
+
+    /** @This tests if low bound is inclusive. */
+    bool low_inclusive() const
+    {
+      return _low.inclusive();
+    }
+
+    /** @This tests if high bound is inclusive. */
+    bool high_inclusive() const
+    {
+      return _high.inclusive();
+    }
+
+    /** @This tests if specified value is included in interval range. */
+    bool contains(const X a) const
+    {
+      if (a == _low.bound())
+	return _low.inclusive();
+      else if (a == _high.bound())
+	return _high.inclusive();
+      else
+	return (!(a < _low.bound()) && a < _high.bound());
+    }
+
+    /** @This tests if two intervals are equals. */
+    bool operator==(const interval &i) const
+    {
+      return _low == i._low && _high == i._high;
+    }
+
+    /** @This prints an interval to stream in the form "@tt {[low, high]}".
+	Square brackets or parenthesis may be used depending on inclusivity. 
+	@alias print
+    */
+    friend std::ostream & operator<<(std::ostream &o, const interval<X, Bound> &i)
+    {
+      o << (i.low_inclusive() ? "[" : "(") << i.low_bound()
+	<< ", " << i.high_bound() << (i.high_inclusive() ? "]" : ")");
+      return o;
+    }
+  };
+
+
+//////////////////////////////////////////////////////////////////////
+//	interval set class
+//////////////////////////////////////////////////////////////////////
+
+  /** @short Interval set class 
+      @module {Interval set}
+      @header dpp/interval_set
+      @main
+      @showvalue
+
+      @This may contain several @ref interval objects to act as an
+      interval set.
+
+      It provides several common boolean set operations like union,
+      intersection, complement and value inclusion test.
+
+      No extra value can be attached to intervals in set; it wouldn't
+      make sense because interval may be splited, joined, created or
+      destroyed by boolean operations.
+
+      @tt X can be a standard scalar type or an user defined type.
+      When a user defined type is used, a custom @tt Limits
+      class parameter must be provided to define upper and lower value
+      limits. The @ref interval_scalar_limits is used by default.
+
+      @tt Bound specify interval bounds inclusivity policy.
+      Acceptable values for @tt Bound template parameter are
+      @ref interval_bound (default), @ref interval_bound_inclusive and
+      @ref interval_bound_exclusive.
+  */
+
+  template <typename X, class Bound, class Limits>
+  class interval_set
+  {
+  public:
+
+    /** Associated @ref interval type */
+    typedef interval<X, Bound> interval_type;
+
+  private:
+    typedef std::vector<interval_type> set_container;
+
+  public:
+    /** Value type */
+    typedef X value_type;
+    /** @ref interval iterator */
+    typedef typename set_container::iterator iterator;
+    /** @ref interval const iterator */
+    typedef typename set_container::const_iterator const_iterator;
+    /** @ref interval set limits class */
+    typedef Limits limits_type;
+
+  private:
+
+    static void union_glob(const set_container &a, unsigned int &i,
+			   const set_container &b, unsigned int &j,
+			   set_container &c, unsigned int &k)
+    {
+      // skip all included intervals
+      while (j < b.size() && b[j]._high.bound() < c[k]._high.bound())
+	j++;
+
+      if (j < b.size())
+	{
+	  // if interval end equal to next interval start
+	  if (((c[k]._high.bound() == b[j]._low.bound())
+	       && (c[k]._high.inclusive() || b[j]._low.inclusive()))
+	  // or interval end greater than next interval start
+	      || (b[j]._low.bound() < c[k]._high.bound()))
+	    {
+	      // join intervals
+	      c[k]._high = b[j++]._high;
+	      // terminal recursion
+	      return union_glob(b, j, a, i, c, k);
+	    }
+	}
+    }
+
+    static interval_set union_(const set_container &a, const set_container &b)
+    {
+      interval_set res;
+      set_container &c = res._set;
+
+      unsigned int i, j, k;
+
+      c.resize(a.size() + b.size());
+
+      for (i = j = k = 0; i < a.size() && j < b.size(); k++)
+	{
+ 	  if (a[i]._low.bound() == b[j]._low.bound())
+	    {
+	      c[k] = a[i];
+	      c[k]._low.set_inclusive(a[i]._low.inclusive() | b[j]._low.inclusive());
+	      i++;
+	      union_glob(a, i, b, j, c, k);
+	    }
+	  else if (a[i]._low.bound() < b[j]._low.bound())
+	    {
+	      c[k] = a[i++];
+	      union_glob(a, i, b, j, c, k);
+	    }
+	  else // if (a[i]._low._bound > b[j]._low._bound)
+	    {
+	      c[k] = b[j++];
+	      union_glob(b, j, a, i, c, k);
+	    }
+	}
+
+      for (; i < a.size(); i++, k++)
+	c[k] = a[i];
+
+      for (; j < b.size(); j++, k++)
+	c[k] = b[j];
+
+      res._set.resize(k);
+
+      return res;
+    }
+
+    static bool pair_intersect(const interval_type &a, const interval_type &b, interval_type &r)
+    {
+      if (b._low.bound() < a._low.bound())
+	r._low = a._low;
+      else // if (a._low.bound() <= b._low.bound())
+	{
+	  r._low = b._low;
+	  if (!a._low.inclusive() && a._low.bound() == b._low.bound())
+	    r._low.set_inclusive(false);
+	}
+
+      if (a._high.bound() < b._high.bound())
+	r._high = a._high;
+      else // if (b._high.bound() <= a._high.bound())
+	{
+	  r._high = b._high;
+	  if (!a._high.inclusive() && a._high.bound() == b._high.bound())
+	    r._high.set_inclusive(false);
+	}
+
+      if (r._high.bound() == r._low.bound())
+	return r._low.inclusive() && r._high.inclusive();
+      else
+	return(r._low.bound() < r._high.bound());
+    }
+
+    static interval_set intersection(const set_container &a, const set_container &b)
+    {
+      interval_set res;
+      set_container &c = res._set;
+
+      unsigned int i, j, k;
+
+      c.resize(a.size() + b.size());
+
+      for (i = j = k = 0; i < a.size() && j < b.size(); )
+	{
+	  if (b[j]._high.bound() < a[i]._low.bound())
+	    while (j < b.size() && b[j]._high.bound() < a[i]._low.bound())
+	      j++;
+	  else if (a[i]._high.bound() < b[j]._low.bound())
+	    while (i < a.size() && a[i]._high.bound() < b[j]._low.bound())
+	      i++;
+	  else 
+	    {
+	      if (pair_intersect(a[i], b[j], c[k]))
+		k++;
+
+	      if (a[i]._high.bound() == b[j]._high.bound())
+		j++, i++;
+	      else if (a[i]._high.bound() < b[j]._high.bound())
+		i++;
+	      else
+		j++;
+	    }
+	}
+
+      res._set.resize(k);
+
+      return res;
+    }
+
+    static interval_set complement(const set_container &a)
+    {
+      if (a.empty())
+	return interval_set(true);
+
+      unsigned int i, j;
+      interval_set res;
+      set_container &r = res._set;
+
+      if (a[0]._low.bound() == limits_type::lower() && a[0]._low.inclusive())
+	{
+	  r.resize(a.size());
+	  r[0]._low.set_bound(a[0]._high.bound());
+	  r[0]._low.set_inclusive(!a[0]._high.inclusive());
+	  j = 1;
+	}
+      else
+	{
+	  r.resize(a.size() + 1);
+	  r[0]._low.set_bound(limits_type::lower());
+	  r[0]._low.set_inclusive(true);
+	  j = 0;
+	}
+
+      for (i = 0; i < r.size() - 1; i++, j++)
+	{
+	  r[i]._high.set_bound(a[j]._low.bound());
+	  r[i]._high.set_inclusive(!a[j]._low.inclusive());
+	  r[i+1]._low.set_bound(a[j]._high.bound());
+	  r[i+1]._low.set_inclusive(!a[j]._high.inclusive());
+	}
+
+      assert(j >= 1);
+
+      if (a[j-1]._high.bound() == limits_type::upper() && a[j-1]._high.inclusive())
+	{
+	  r.pop_back();
+	}
+      else
+	{
+	  r[i]._high.set_bound(limits_type::upper());
+	  r[i]._high.set_inclusive(true);
+	}
+
+      return res;
+    }
+
+    unsigned int dicho(const X a) const
+    {
+      unsigned int min_idx = 0;
+      unsigned int max_idx = _set.size();
+
+      assert(!_set.empty());
+
+      // dichotomic search
+      while (max_idx - min_idx > 1)
+	{
+	  unsigned int p = (max_idx + min_idx) / 2;
+
+	  if (a < _set[p]._low.bound())
+	    max_idx = p;
+	  else
+	    min_idx = p;
+	}
+
+      return min_idx;
+    }
+
+  public:
+
+    /** @This creates an empty interval set */
+    interval_set()
+    {
+    }
+
+    /** @This creates an empty or whole interval set */
+    interval_set(bool whole)
+    {
+      if (whole)
+	_set.push_back(interval_type(limits_type::lower(),
+				     limits_type::upper()));
+    }
+
+    /** @This creates an interval set including values in given @ref interval */
+    interval_set(const interval_type &i)
+    {
+      _set.push_back(i);
+    }
+
+    /** @This creates an interval set including values in [@tt low, @tt high] range.
+	@see interval::__interval_1__ */
+    interval_set(const X low, const X high)
+    {
+      _set.push_back(interval_type(low, high));
+    }
+
+    /** @This creates an interval set including values in range {@tt low, @tt high} with given inclusivity
+	@see interval::__interval_2__ */
+    interval_set(const X low, bool low_inclusive,
+		 const X high, bool high_inclusive)
+    {
+      _set.push_back(interval_type(low, low_inclusive, high, high_inclusive));
+    }
+
+    /** @This resets the interval set to empty state */
+    void clear()
+    {
+      _set.clear();
+    }
+
+    /** @This tests if interval set is empty */
+    bool empty()
+    {
+      return _set.empty();
+    }
+
+    /** @This tests if interval set is whole */
+    bool whole()
+    {
+      return (!_set.empty()
+	      && _set.back()._low.bound() == limits_type::lower()
+	      && _set.back()._high.bound() == limits_type::upper());
+    }
+
+    /** @This returns a new interval set being the union of the two interval sets */
+    interval_set operator|(const interval_set &i) const
+    {
+      return union_(_set, i._set);
+    }
+
+    /** @This replaces the current interval set by the union with given interval set */
+    interval_set & operator|=(const interval_set &i)
+    {
+      return *this = *this | i; // FIXME write optimized version
+    }
+
+    /** @This replaces the current interval set by the union with given interval */
+    interval_set & operator|=(const interval_type &i)
+    {
+      return *this = *this | interval_set(i); // FIXME write optimized version
+    }
+
+    /** @This returns a new interval set being the intersection of the two interval sets */
+    interval_set operator&(const interval_set &i) const
+    {
+      return intersection(_set, i._set);
+    }
+
+    /** @This replaces the current interval set by the intersection with given interval set */
+    interval_set & operator&=(const interval_set &i)
+    {
+      return *this = *this & i; // FIXME write optimized version
+    }
+
+    /** @This replaces the current interval set by the intersection with given interval */
+    interval_set & operator&=(const interval_type &i)
+    {
+      return *this = *this & interval_set(i); // FIXME write optimized version
+    }
+
+    /** @This returns the complementary interval set */
+    interval_set operator~() const
+    {
+      return complement(_set);
+    }
+
+    /** @This returns a new interval set being the exclusive or of the two interval sets */
+    interval_set operator^(const interval_set &i) const
+    {
+      return (*this & ~i) | (~*this & i);
+    }
+
+    /** @This replaces the current interval set by the exclusive or with given interval set */
+    interval_set & operator^=(const interval_set &i)
+    {
+      return *this = *this ^ i;
+    }
+
+    /** @This replaces the current interval set by the exclusive or with given interval */
+    interval_set & operator^=(const interval_type &i)
+    {
+      return *this = *this ^ interval_set(i);
+    }
+
+    /** @This returns the interval which contains the given value.
+	This throws a @ref std::out_of_range exception if no matching
+	interval is available in set. */
+    interval_type get_interval(const X a) const throw (std::out_of_range)
+    {
+      if (_set.empty())
+	throw std::out_of_range("empty interval_set");
+
+      unsigned int p = dicho(a);
+
+      if (!_set[p].contains(a))
+	throw std::out_of_range("no matching interval found");
+
+      return _set[p];
+    }
+
+    /** @This tests if specified value is included in interval set
+	@alias contains_1
+     */
+    bool contains(const X a) const
+    {
+      return !_set.empty() && _set[dicho(a)].contains(a);
+    }
+
+    /** @This tests if specified interval set is included in interval set */
+    bool contains(const interval_set &i) const
+    {
+      return (i & *this) == i; // FIXME write optimized version
+    }
+
+    /** @This is a shortcut for @ref __contains_1__ */
+    bool operator[](const X a) const
+    {
+      return contains(a);
+    }
+
+    /** @This tests if two interval sets are equals */
+    bool operator==(const interval_set &i) const
+    {
+      if (_set.size() != i._set.size())
+	return false;
+
+      for (unsigned int j = 0; j < _set.size(); j++)
+	if (!(_set[j] == i._set[j]))
+	  return false;
+
+      return true;
+    }
+
+    /** @This returns an interval set iterator. It can be
+	used to iterator over all @ref interval contained in the set. */
+    iterator begin()
+    {
+      return _set.begin();
+    }
+
+    /** @This returns an interval set end iterator. */
+    iterator end()
+    {
+      return _set.end();
+    }
+
+    /** @This returns an interval set const iterator. It can be
+	used to iterator over all @ref interval contained in the set. */
+    const_iterator begin() const
+    {
+      return _set.begin();
+    }
+
+    /** @This returns an interval set end iterator. */
+    const_iterator end() const
+    {
+      return _set.end();
+    }
+
+    /** @This prints interval set to stream by iterating over all @ref interval
+	present in the set using @ref interval::__print__
+    */
+    friend std::ostream & operator<<(std::ostream &o, const interval_set<X, Bound, Limits> &is)
+    {
+      for (typename interval_set<X, Bound, Limits>::const_iterator i = is.begin(); i != is.end(); i++)
+	o << *i;
+      return o;
+    }
+
+  private:
+
+    set_container _set;
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/linked_list
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/linked_list	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/linked_list	(revision 283)
@@ -0,0 +1,936 @@
+/* -*- c++ -*-
+
+   C++ Internal storage linked list container.
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2008-2011 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_LINKED_LIST_HH_
+#define DPP_LINKED_LIST_HH_
+
+#include <iterator>
+#include <cassert>
+
+/** @file @module{Linked list container} */
+
+namespace dpp {
+
+class linked_list_node;
+
+template <class X, int id = -1, bool smart = false>
+class linked_list_item;
+
+template <class X, int id = -1, bool smart = false, class ItemBase = X>
+class linked_list;
+
+template <class X, int id, class Xnode, bool forward, bool smart>
+class linked_list_iterator;
+
+//////////////////////////////////////////////////////////////////////
+//	linked_list node class
+//////////////////////////////////////////////////////////////////////
+
+/** @short Linked list internal node class
+    @module{Linked list container}
+    @header dpp/linked_list
+    @internal
+ */
+
+class linked_list_node
+{
+  template <class, int, bool, class> friend class linked_list;
+  template <class, int, bool> friend class linked_list_item;
+  template <class, int, class, bool, bool> friend class linked_list_iterator;
+
+  linked_list_node *m_next;
+  linked_list_node *m_prev;
+
+  linked_list_node(linked_list_node *next, linked_list_node *prev)
+    : m_next(next),
+      m_prev(prev)
+  {
+  }
+
+  linked_list_node()
+  {
+  }
+
+  linked_list_node(linked_list_node &l)
+    : m_next(l.m_next),
+      m_prev(l.m_prev)
+  {
+  }
+
+};
+
+//////////////////////////////////////////////////////////////////////
+//	linked_list iterator class
+//////////////////////////////////////////////////////////////////////
+
+/** @short Linked list iterator class
+    @module{Linked list container}
+    @header dpp/linked_list
+    @internal
+ */
+
+template <class X, int id, class Xnode, bool forward, bool smart>
+class linked_list_iterator
+{
+  template <class, int, bool, class> friend class linked_list;
+  template <class, int, bool> friend class linked_list_item;
+  template <class, int, class, bool, bool> friend class linked_list_iterator;
+
+  linked_list_iterator(Xnode *i)
+    : m_item(i)
+  {
+  }
+
+  Xnode *m_item;
+
+public:
+
+  /** @multiple Standard STL container typedef. */
+  typedef linked_list_item<X, id, smart> item_type;
+  typedef X value_type;
+  typedef X & reference;
+  typedef X * pointer;
+  typedef ssize_t difference_type;
+  typedef std::bidirectional_iterator_tag iterator_category;
+  /** */
+
+  linked_list_iterator(const linked_list_iterator &i)
+    : m_item(i.m_item)
+  {
+  }
+
+  template <class T, class N>
+  linked_list_iterator(const linked_list_iterator<T, id, N, forward, smart> &i)
+    : m_item(i.m_item)
+  {
+    // raise error on invalid iterator convertion
+    static_cast<X*>((T*)0);
+  }
+
+  linked_list_iterator()
+  {
+  }
+
+  linked_list_iterator & operator++()
+  {
+    assert(m_item->m_next || !"iterator points to orphan item");
+    m_item = forward ? m_item->m_next : m_item->m_prev;
+    return *this;
+  }
+
+  linked_list_iterator operator++(int)
+  {
+    assert(m_item->m_next || !"iterator points to orphan item");
+    linked_list_iterator tmp(*this);
+    m_item = forward ? m_item->m_next : m_item->m_prev;
+    return tmp;
+  }
+
+  linked_list_iterator & operator--()
+  {
+    assert(m_item->m_next || !"iterator points to orphan item");
+    m_item = forward ? m_item->m_prev : m_item->m_next;
+    return *this;
+  }
+
+  linked_list_iterator operator--(int)
+  {
+    assert(m_item->m_next || !"iterator points to orphan item");
+    linked_list_iterator tmp(*this);
+    m_item = forward ? m_item->m_prev : m_item->m_next;
+    return tmp;
+  }
+
+  X & operator*() const
+  {
+    return const_cast<X &>(
+	     static_cast<const X &>(
+	       static_cast<const item_type &>(*m_item)));
+  }
+
+  X * operator->() const
+  {
+    return const_cast<X *>(
+	     static_cast<const X *>(
+	       static_cast<const item_type *>(m_item)));
+  }
+
+  bool operator==(const linked_list_iterator &i) const
+  {
+    return m_item == i.m_item;
+  }
+
+  bool operator!=(const linked_list_iterator &i) const
+  {
+    return m_item != i.m_item;
+  }
+
+};
+
+//////////////////////////////////////////////////////////////////////
+//	linked_list container class
+//////////////////////////////////////////////////////////////////////
+
+/** @short Linked list container class
+    @module{Linked list container}
+    @header dpp/linked_list
+    @main
+    @showvalue
+
+    @This implements the internal storage linked list container.
+
+    Item class must inherit from the @ref linked_list_item class
+    in order to be a valid @ref linked_list container item.
+
+    The @tt id template parameter may be used to define several
+    distinct list containers so that items can be part of more than
+    one list.
+
+    Linked list can be used in @tt smart mode. Smart lists will automatically
+    remove items from current list when inserting in an other list. Non-smart
+    list will raise false assertion if non-orphan items are used the
+    wrong way.
+
+    When the linked list contained class doesn't directly inherit from
+    @ref linked_list_item, the base class which inherits from @ref
+    linked_list_item must be passed as @tt ItemBase template parameter.
+*/
+
+template <class X, int id, bool smart, class ItemBase>
+class linked_list
+{
+  template <class, int, bool> friend class linked_list_item;
+
+  typedef bool _predicate(const X &a, const X &b);
+
+public:
+  /** @multiple Standard STL container typedef. */
+
+  typedef linked_list_item<ItemBase, id, smart> item_type;
+
+  typedef linked_list_iterator<X, id, linked_list_node, true, smart> iterator;
+  typedef linked_list_iterator<X, id, const linked_list_node, true, smart> const_iterator;
+  typedef linked_list_iterator<X, id, linked_list_node, false, smart> reverse_iterator;
+  typedef linked_list_iterator<X, id, const linked_list_node, false, smart> const_reverse_iterator;
+
+  typedef X value_type;
+  typedef X & reference;
+  typedef const X & const_reference;
+  typedef X * pointer;
+  typedef const X * const_pointer;
+  typedef size_t size_type;
+  typedef ssize_t difference_type;
+  /** */
+
+private:
+
+  void _empty()
+  {
+    m_root.m_next = m_root.m_prev = &m_root;
+  }
+
+  static void _insert_post(linked_list_node *a, item_type *b)
+  {
+    static_cast<X*>(b)->linked_list_pre_insert();
+    b->_check_orphan();
+    b->m_prev = a;
+    a->m_next->m_prev = b;
+    b->m_next = a->m_next;
+    a->m_next = b;
+  }
+
+  static void _insert_pre(linked_list_node *a, item_type *b)
+  {
+    static_cast<X*>(b)->linked_list_pre_insert();
+    b->_check_orphan();
+    b->m_next = a;
+    a->m_prev->m_next = b;
+    b->m_prev = a->m_prev;
+    a->m_prev = b;
+  }
+
+  static void _remove(item_type *pos)
+  {
+    pos->_check_not_orphan();
+    pos->m_prev->m_next = pos->m_next;
+    pos->m_next->m_prev = pos->m_prev;
+    pos->_set_orphan();
+    static_cast<X*>(pos)->linked_list_post_remove();
+  }
+
+  static void _swap(item_type *a, item_type *b)
+  {
+    a->m_next->m_prev = a->m_prev->m_next = b;
+    b->m_next->m_prev = b->m_prev->m_next = a;
+    std::swap(a->m_prev, b->m_prev);
+    std::swap(a->m_next, b->m_next);
+  }
+
+  static void _replace(item_type *out, item_type *in)
+  {
+    if (out == in)
+      return;
+    out->_check_not_orphan();
+    static_cast<X*>(in)->linked_list_pre_insert();
+    in->_check_orphan();
+    out->m_prev->m_next = out->m_next->m_prev = in;
+    in->m_prev = out->m_prev;
+    in->m_next = out->m_next;
+    out->_set_orphan();
+    static_cast<X*>(out)->linked_list_post_remove();
+  }
+
+  // rebuild from a null terminated singly list
+  void _rebuild(linked_list_node *list)
+  {
+    linked_list_node *prev;
+    m_root.m_next = list;
+
+    for (prev = &m_root; list; list = list->m_next)
+      {
+	list->m_prev = prev;
+	prev = list;
+      }
+
+    prev->m_next = &m_root;
+    m_root.m_prev = prev;
+  }
+
+  // default sort predicate
+  static bool _default_predicate(const X &a, const X &b)
+  {
+    return a < b;
+  }
+
+  // sublist merging function
+  static linked_list_node * _merge(linked_list_node *a, linked_list_node *b, _predicate *func)
+  {
+    linked_list_node *first, *last;
+
+    /* choose list head */
+    if (func(static_cast<X&>(static_cast<item_type &>(*a)),
+	     static_cast<X&>(static_cast<item_type &>(*b))))
+      a = (last = first = a)->m_next;
+    else
+      b = (last = first = b)->m_next;
+
+    /* merge lists */
+    while (a && b)
+      if (func(static_cast<X&>(static_cast<item_type &>(*a)),
+	       static_cast<X&>(static_cast<item_type &>(*b))))
+	a = (last = last->m_next = a)->m_next;
+      else
+	b = (last = last->m_next = b)->m_next;
+
+    last->m_next = a ? a : b;
+
+    return first;
+  }
+
+  linked_list(const linked_list &l);
+  linked_list & operator=(const linked_list &);
+
+  linked_list_node m_root;
+
+public:
+
+  /** @This creates an empty list. */
+  linked_list()
+    : m_root(&m_root, &m_root)
+  {
+  }
+
+  /** @This set all contained items as orphan. */
+  ~linked_list()
+  {
+    for (linked_list_node *i = m_root.m_prev; i != &m_root; i = i->m_prev)
+      {
+	item_type *t = static_cast<item_type*>(i);
+	t->_set_orphan();
+	static_cast<X*>(t)->linked_list_post_remove();
+      }
+  }
+
+  /** @This creates a list from item iterators. */
+  template <class input_iterator>
+  linked_list(input_iterator first, input_iterator last)
+    : m_root(&m_root, &m_root)
+  {
+    for (input_iterator i = first; i != last; i++)
+      _insert_pre(&m_root, &*i);
+  }
+
+  /** @This push an item in front of this list. */
+  void push_front(X &i)
+  {
+    _insert_post(&m_root, static_cast<item_type*>(&i));
+  }
+
+  /** @This push an item at the end of this list.
+      @csee linked_list_item::push_back
+   */
+  void push_back(X &i)
+  {
+    _insert_pre(&m_root, static_cast<item_type*>(&i));
+  }
+
+  /** @This removes first item from this list.
+      @csee linked_list_item::push_back
+   */
+  void pop_front()
+  {
+    _remove(static_cast<item_type*>(m_root.m_next));
+  }
+
+  /** @This removes last item from this list. */
+  void pop_back()
+  {
+    _remove(static_cast<item_type*>(m_root.m_prev));
+  }
+
+  /** @This inserts an item at specified location in this list.
+      @return an iterator to inserted item */
+  iterator insert(const iterator &pos, X &i)
+  {
+    item_type *li = static_cast<item_type*>(&i);
+    _insert_pre(pos.m_item, li);
+    return iterator(li);
+  }
+
+  /** @This inserts multiple items at specified position in this list.
+      @return an iterator to first inserted item */
+  template <class input_iterator>
+  iterator insert(const iterator &pos, input_iterator first, input_iterator last)
+  {
+    for (input_iterator i = first; i != last; i++)
+      _insert_pre(pos.m_item, &*i);
+    return iterator(static_cast<item_type*>(&*first));
+  }
+
+  /** @This removes the item at specified position in this list.
+      @return an iterator to next item */
+  iterator erase(iterator pos)
+  {
+    linked_list_node *next = pos.m_item->m_next;
+    _remove(static_cast<item_type*>(pos.m_item));
+    return iterator(static_cast<item_type*>(next));
+  }
+
+  /** @This removes all items in specified [range) in this list.
+      @return an iterator to the next item */
+  iterator erase(iterator first, iterator last)
+  {
+    item_type *f = static_cast<item_type*>(&*first);
+    item_type *l = static_cast<item_type*>(&*last);
+
+    f->m_prev->m_next = l;
+
+    for (linked_list_node *i = l->m_prev; i != f->m_prev; i = i->m_prev)
+      {
+	item_type *t = static_cast<item_type*>(i);
+	t->_set_orphan();
+	static_cast<X*>(t)->linked_list_post_remove();
+      }
+
+    l->m_prev = f->m_prev;
+
+    return iterator(l);
+  }
+
+  /** @This swaps lists contents. */
+  void swap(linked_list &x)
+  {
+    _swap(static_cast<item_type*>(&m_root),
+	  static_cast<item_type*>(&x.m_root));
+  }
+
+  /** @This removes all items from this list. */
+  void clear()
+  {
+    for (linked_list_node *i = m_root.m_prev; i != &m_root; i = i->m_prev)
+      {
+	item_type *t = static_cast<item_type*>(i);
+	t->_set_orphan();
+	static_cast<X*>(t)->linked_list_post_remove();
+      }
+
+    m_root.m_next = m_root.m_prev = &m_root;
+  }
+
+  /** @This removes all items matching specified value from this list
+      @csee linked_list_item::remove
+  */
+  void remove(const X &v)
+  {
+    for (iterator i = begin(); i != end();)
+      {
+	if (*i == v)
+	  i = erase(i);
+	else
+	  ++i;
+      }
+  }
+
+  /** @This replaces an item by an other item in this list.
+      @return an iterator to replacement item
+      @csee linked_list_item::replace */
+  static iterator replace(X &out, X &in)
+  {
+    item_type *i = static_cast<item_type*>(&in);
+    _replace(i, static_cast<item_type*>(&out));
+    return iterator(i);
+  }
+
+  /** @This tests if this list is empty */
+  bool empty() const
+  {
+    return m_root.m_next == &m_root;
+  }
+
+  /** @This returns list item count, takes O(n). */
+  size_type size() const
+  {
+    size_t s = 0;
+
+    for (const_iterator i = begin(); i != end(); ++i)
+      s++;
+
+    return s;
+  }
+
+  /** @This returns maximum container size */
+  size_type max_size() const
+  {
+    return (size_type)(-1);
+  }
+
+  /** @This appends all items from the given list to the end of this list */
+  void append(linked_list &list)
+  {
+    if (!list.empty())
+      {
+	list.m_root.m_prev->m_next = &m_root;
+	list.m_root.m_next->m_prev = m_root.m_prev;
+	m_root.m_prev->m_next = list.m_root.m_next;
+	m_root.m_prev = list.m_root.m_prev;
+	list._empty();
+      }
+  }
+
+  /** @This appends all item from the given list in front of this list */
+  void prepend(linked_list &list)
+  {
+    if (!list.empty())
+      {
+	list.m_root.m_next->m_prev = &m_root;
+	list.m_root.m_prev->m_next = m_root.m_next;
+	m_root.m_next->m_prev = list.m_root.m_prev;
+	m_root.m_next = list.m_root.m_next;
+	list._empty();
+      }
+  }
+
+  /** @This merges with specified ordered list according to specified sort predicate */
+  void merge(linked_list &list, _predicate *func)
+  {
+    _rebuild(_merge(m_root.m_next, list.m_root.m_next, func));
+    list._empty();
+  }
+
+  /** @This merges with specified ordered list using default predicate */
+  void merge(linked_list &list)
+  {
+    merge(list, _default_predicate);
+  }
+
+  /** @This sorts this list according to specified sort predicate */
+  void sort(_predicate *func)
+  {
+    /* Fast linked list stack based merge sort algorithm by Alexandre Becoulet */
+
+    if (m_root.m_prev == m_root.m_next)
+      return;
+
+    unsigned int n = 0;		/* index of current node pair */
+    linked_list_node *tail = m_root.m_next; /* remaining unprocessed nodes */
+    linked_list_node *stack[41]; /* we are able to sort 2^40 nodes here */
+    linked_list_node **s = stack;
+
+    m_root.m_prev->m_next = 0;
+
+    while (tail)
+      {
+	unsigned int idx, tmp;
+
+	/* Pick 2 nodes */
+	linked_list_node *a = tail;
+	linked_list_node *b = tail->m_next;
+
+	if (!b)
+	  {
+	    *s++ = a;
+	    break;
+	  }
+
+	tail = b->m_next;
+
+	/* Create a sorted pair list and push it on stack */
+	if (func(static_cast<X&>(static_cast<item_type &>(*a)),
+	         static_cast<X&>(static_cast<item_type &>(*b))))
+	  ((*s = a)->m_next = b)->m_next = 0;
+	else
+	  ((*s = b)->m_next = a)->m_next = 0;
+
+	s++;
+
+	/* Reduce stack by merging top lists as if we were building a
+	   complete binary tree from leaf nodes. We compute needed
+	   merge count from bits change in pair index. */
+	tmp = n++;
+	for (idx = n ^ tmp; idx &= idx - 1; s--)
+	  s[-2] = _merge(s[-2], s[-1], func);
+      }
+
+    /* Merge all remaining lists */
+    while (s-- > stack + 1)
+      s[-1] = _merge(s[-1], s[0], func);
+
+    /* rebuild prev links and root */
+    _rebuild(stack[0]);
+  }
+
+  /** @This sorts this list using default predicate */
+  void sort()
+  {
+    sort(_default_predicate);
+  }
+
+  /** @This returns a reference to the first list item */
+  X & front() const
+  {
+    return static_cast<X &>(static_cast<item_type &>(*m_root.m_next));
+  }
+
+  /** @This returns a reference to the last list item */
+  X & back() const
+  {
+    return static_cast<X &>(static_cast<item_type &>(*m_root.m_prev));
+  }
+
+  /** @This returns list begin iterator */
+  iterator begin()
+  {
+    return iterator(m_root.m_next);
+  }
+
+  /** @This return list begin const iterator */
+  const_iterator begin() const
+  {
+    return const_iterator(m_root.m_next);
+  }
+
+  /** @This returns list end iterator */
+  iterator end()
+  {
+    return iterator(&m_root);
+  }
+
+  /** @This returns list end const iterator */
+  const_iterator end() const
+  {
+    return const_iterator(&m_root);
+  }
+
+  /** @This returns list begin reverse iterator */
+  reverse_iterator rbegin()
+  {
+    return reverse_iterator(m_root.m_prev);
+  }
+
+  /** @This returns list begin reverse const iterator */
+  const_reverse_iterator rbegin() const
+  {
+    return const_reverse_iterator(m_root.m_prev);
+  }
+
+  /** @This returns list end reverse iterator */
+  reverse_iterator rend()
+  {
+    return reverse_iterator(&m_root);
+  }
+
+  /** @This returns list end reverse const iterator */
+  const_reverse_iterator rend() const
+  {
+    return const_reverse_iterator(&m_root);
+  }
+
+  /** @This clears this list and push a single item */
+  linked_list & operator=(X &i)
+  {
+    clear();
+    push_back(i);
+    return *this;
+  }
+
+  /** @This push an item at the end of this list */
+  linked_list & operator+=(X &i)
+  {
+    push_back(i);
+    return *this;
+  }
+
+  /** @This removes the given item from this list */
+  linked_list & operator-=(X &i)
+  {
+    _remove(static_cast<item_type*>(&i));
+    return *this;
+  }
+};
+
+//////////////////////////////////////////////////////////////////////
+//	linked_list item class
+//////////////////////////////////////////////////////////////////////
+
+/** @internal */
+class linked_list_item_vbase
+{
+public:
+  /* These empty default implementations are defined in a virtual base
+     class to avoid ambiguity when user class inherits from multiple
+     linked_list_item bases */
+  void linked_list_post_remove()
+  {
+  }
+
+  void linked_list_pre_insert()
+  {
+  }
+};
+
+/** @short Linked list item class
+    @module{Linked list container}
+    @header dpp/linked_list
+
+    Item class must inherit from this class to be a valid @ref linked_list item.
+
+    Multiple inheritance with different @tt id values enables items to
+    be part of several distinct linked list containers simultaneously.
+
+    All membership management functions in this class are @tt
+    protected. They may still be selectively exposed publicly in the
+    item class by adding an associated @tt using directive
+    in the @tt public inherited class part.
+*/
+
+template <class X, int id, bool smart>
+class linked_list_item
+  : public linked_list_node
+  , virtual public linked_list_item_vbase
+{
+  template <class, int, bool, class> friend class linked_list;
+  template <class, int, class, bool, bool> friend class linked_list_iterator;
+
+protected:
+  /** Associated list container type */
+  typedef linked_list<X, id, smart> list_type;
+
+private:
+
+  linked_list_item(linked_list_item *next, linked_list_item *prev)
+    : linked_list_node(next, prev)
+  {
+  }
+
+  void _check_not_orphan() const
+  {
+    assert(linked_list_node::m_next != 0 || !"bad operation, item is not part of a linked_list");
+  }
+
+  void _check_orphan()
+  {
+    if (smart)
+      {
+	// smartly remove from current container if any
+	if (linked_list_node::m_next != 0)
+	  list_type::_remove(this);
+      }
+    else
+      {
+	assert(linked_list_node::m_next == 0 || !"bad operation, item is currently part of a linked_list");
+      }
+  }
+
+  void _set_orphan()
+  {
+    linked_list_node::m_next = 0;
+  }
+
+protected:
+  typedef linked_list_iterator<X, id, linked_list_node, true, smart> iterator;
+  typedef linked_list_iterator<X, id, const linked_list_node, true, smart> const_iterator;
+
+  /** @This constructs an orphan list item. */
+  linked_list_item()
+  {
+    _set_orphan();
+  }
+
+  ~linked_list_item()
+  {
+    _check_orphan();    
+  }
+
+  /** @This constructs a list item copy. Items copies are orphan. */
+  linked_list_item(const linked_list_item &i)
+  {
+    _set_orphan();
+  }
+
+  /** @This @b preserves list current membership */
+  linked_list_item & operator=(const linked_list_item &i)
+  {
+    // do not change list membership
+    return *this;
+  }
+
+  /** @This tests if item is part of a list */
+  bool orphan()
+  {
+    return linked_list_node::m_next == 0;
+  }
+
+  /** @This exchanges this item with specified item. Both items must
+      be part of a list.
+      @return an iterator to the replacement item.
+  */
+  iterator swap(X &in)
+  {
+    linked_list_item *i = static_cast<linked_list_item*>(&in);
+    _check_not_orphan();
+    i->_check_not_orphan();
+    list_type::_swap(this, i);
+    return iterator(i);
+  }
+
+  /** @This replaces this item in its list by the given orphan item.
+      @return an iterator to the replacement item.
+  */
+  iterator replace(X &in)
+  {
+    linked_list_item *i = static_cast<linked_list_item*>(&in);
+    list_type::_replace(this, static_cast<linked_list_item*>(i));
+    return iterator(i);
+  }
+
+  /** @This removes item from its current list */
+  void remove()
+  {
+    list_type::_remove(this);
+  }
+
+  /** @This inserts an item after this item in the current list */
+  void push_back(linked_list_item &i)
+  {
+    _check_not_orphan();
+    list_type::_insert_post(this, static_cast<linked_list_item*>(&i));
+  }
+
+  /** @This inserts an item before this item in the current list */
+  void push_front(linked_list_item &i)
+  {
+    _check_not_orphan();
+    list_type::_insert_pre(this, static_cast<linked_list_item*>(&i));
+  }
+
+  /** @This returns an iterator to this item in the list */
+  iterator current()
+  {
+    _check_not_orphan();
+    return iterator(this);
+  }
+
+  /** @This returns a const iterator to this item in the list */
+  const_iterator current() const
+  {
+    _check_not_orphan();
+    return const_iterator(this);
+  }
+
+  /** @This returns an iterator to the next item in the list */
+  iterator next()
+  {
+    _check_not_orphan();
+    return iterator(linked_list_node::m_next);
+  }
+
+  /** @This returns a const iterator to the next item in the list */
+  const_iterator next() const
+  {
+    _check_not_orphan();
+    return const_iterator(linked_list_node::m_next);
+  }
+
+  /** @This returns an iterator to the previous item in the list */
+  iterator prev()
+  {
+    _check_not_orphan();
+    return iterator(linked_list_node::m_prev);
+  }
+
+  /** @This returns a const iterator to the previous item in the list */
+  const_iterator prev() const
+  {
+    _check_not_orphan();
+    return const_iterator(linked_list_node::m_prev);
+  }
+
+#ifdef __MKDOC__
+  /* actual definitions are located in the linked_list_item_vbase class */
+
+  /** @This is called when the object has been removed from a linked
+      list. The call is performed on a reference to @tt X class so a
+      virtual prototype must be declared in the @tt X class to
+      override this function from further derived classes. This
+      default implementation is empty. */
+  inline void linked_list_post_remove();
+
+  /** @This is called when the object becomes part of a linked list. The
+      call is performed on a reference to @tt X class so a virtual
+      prototype must be declared in the @tt X class to override this
+      function from further derived classes. This default
+      implementation is empty. */
+  inline void linked_list_pre_insert();
+
+#endif
+
+};
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/radix_sort
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/radix_sort	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/radix_sort	(revision 283)
@@ -0,0 +1,271 @@
+/* -*- c++ -*-
+
+   Template Radix sort implementation
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2012 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_RADIX_SORT_HH_
+#define DPP_RADIX_SORT_HH_
+
+#include <algorithm>
+#include <cassert>
+
+#include <stdint.h>
+
+/** @file @module{Radix sort} */
+
+namespace dpp {
+
+  /** @This class may be specialized to describe how radix are
+      extracted from values for a given type. Specializations are
+      provided for integer and floating-point types. */
+  template <typename X, size_t bits>
+  struct radix_sort_type
+  {
+    static unsigned int extract(const X x, size_t pos)
+    {
+      X::_requires_8bits_radix_width_for_custom_types();
+    }
+  };
+
+  /** @This provides a generic byte-slicing radix extraction function. */
+  template <typename X>
+  struct radix_sort_type<const X &, 8>
+  {
+    static unsigned int extract(const X x, size_t pos)
+    {
+      const uint8_t *d = (const uint8_t *)&x;
+      return d[pos];
+    }
+  };
+
+  /** @internal */
+#define _DPP_RADIX_SORT_INT(type)					\
+  /** @This class provides a radix extaction function for @tt{type} integers */	\
+  template <size_t bits>						\
+  struct radix_sort_type<type, bits>					\
+  {									\
+    static const size_t _bsize = 1 << bits;				\
+    static const size_t _passes = sizeof(type) * 8 / bits + (bits % 8 != 0); \
+									\
+    static unsigned int extract(type x, size_t pos)			\
+    {									\
+      return (x >> (bits * pos)) & ((1 << bits) - 1);			\
+    }									\
+  }
+
+  _DPP_RADIX_SORT_INT(signed char);
+  _DPP_RADIX_SORT_INT(unsigned char);
+  _DPP_RADIX_SORT_INT(signed short);
+  _DPP_RADIX_SORT_INT(unsigned short);
+  _DPP_RADIX_SORT_INT(signed int);
+  _DPP_RADIX_SORT_INT(unsigned int);
+  _DPP_RADIX_SORT_INT(signed long);
+  _DPP_RADIX_SORT_INT(unsigned long);
+  _DPP_RADIX_SORT_INT(signed long long);
+  _DPP_RADIX_SORT_INT(unsigned long long);
+
+  /** @internal */
+#define _DPP_RADIX_SORT_FLOAT(type)					\
+  /** @This class provides a radix extaction function for @tt{type} floating-point values */	\
+  template <size_t bits>						\
+  struct radix_sort_type<type, bits>					\
+  {									\
+    static const size_t _bsize = 1 << bits;				\
+    static const size_t _passes = sizeof(type) * 8 / bits + (bits % 8 != 0); \
+									\
+    static unsigned int extract(type x, size_t pos)			\
+    {									\
+      switch (sizeof(type))						\
+	{								\
+          case 4: {							\
+	    int32_t v = *(int32_t*)&x;				\
+	    return ((((v >> 31) | (1 << 31)) ^ v) >> (bits * pos)) & ((1 << bits) - 1); \
+	  }								\
+          case 8: {							\
+            int64_t v = *(int64_t*)&x;				\
+	    return ((((v >> 63) | (1ULL << 63)) ^ v) >> (bits * pos)) & ((1 << bits) - 1); \
+	  }								\
+	default:							\
+	  std::abort();							\
+	}								\
+    }									\
+  }
+
+  _DPP_RADIX_SORT_FLOAT(float);
+  _DPP_RADIX_SORT_FLOAT(double);
+
+  /** @internal */
+  template <typename X, size_t bits>
+  struct _radix_sort
+  {
+    static const size_t _bsize = 1 << bits;
+    static const size_t _passes = sizeof(X) * 8 / bits + (bits % 8 != 0); \
+
+    /** @This performs actual sorting */
+    static void sort(X *in, X *next_in, X *out, size_t len)
+    {
+      size_t hist[_passes][_bsize];
+
+      // zero histograms
+      for (size_t j = 0; j < _passes; j++)
+	for (size_t i = 0; i < _bsize; i++)
+	  hist[j][i] = 0;
+
+      // compute histograms
+      for (size_t i = 0; i < len; i++)
+	for (size_t j = 0; j < _passes; j++)
+	  hist[j][radix_sort_type<X, bits>::extract(in[i], j)]++;
+
+      // multiple passes stable radix-sort
+      for (size_t j = 0; j < _passes; j++)
+	{
+	  uintptr_t offset[_bsize], o;
+
+	  // compute offsets
+	  o = offset[0] = 0;
+	  for (size_t i = 1; i < _bsize; i++)
+	    o = offset[i] = o + hist[j][i - 1];
+
+	  // reorder array
+	  for (size_t i = 0; i < len; i++)
+	    {
+	      size_t x = radix_sort_type<X, bits>::extract(in[i], j);
+	      out[offset[x]++] = in[i];
+	    }
+
+	  // swap input/output arrays for next pass
+	  in = next_in;
+	  std::swap(in, out);
+	  next_in = in;
+	}
+    }
+
+    /** @This performs sorting and final array copy when number of passes are odd
+	and sorting result must be stored back in original array. */
+    static void sort_in(X *in, size_t len)
+    {
+      X tmp[len];
+
+      sort(in, in, tmp, len);
+
+      if (_passes % 2)
+	for (size_t i = 0; i < len; i++)
+	  in[i] = tmp[i];
+    }
+    
+    /** @This performs input array copy to temporary storage when
+	number of passes are odd and sorting. */
+    static void sort_out(const X *in, X *out, size_t len)
+    {
+      if (_passes % 2)
+	{
+	  X tmp[len];
+
+	  for (size_t i = 0; i < len; i++)
+	    tmp[i] = in[i];
+	  sort(tmp, tmp, out, len);
+	}
+      else if (_passes > 1)
+	{
+	  X tmp[len];
+	  sort((X*)in, out, tmp, len);
+	}
+      else
+	{
+	  sort((X*)in, 0, out, len);
+	}
+    }
+  };
+
+  /** @This function performs radix-sort on container iterators. Radix
+      width is 8 bits. */
+  template <typename iterator>
+  void radix_sort(const iterator &begin, const iterator &end)
+  {
+    typedef typename iterator::value_type type;
+    size_t len = end - begin;
+
+    _radix_sort<type, 8>::sort_in(&*begin, len);
+  }
+
+  /** @This function performs radix-sort on container
+      iterators. Specified radix bit width is used. */
+  template <typename iterator, size_t bits>
+  void radix_sort(const iterator &begin, const iterator &end)
+  {
+    typedef typename iterator::value_type type;
+    size_t len = end - begin;
+
+    _radix_sort<type, bits>::sort_in(&*begin, len);
+  }
+
+  /** @This function performs radix-sort on array. Radix
+      width is 8 bits. */
+  template <typename X>
+  void radix_sort(X *begin, X *end)
+  {
+    typedef X type;
+    size_t len = end - begin;
+
+    _radix_sort<type, 8>::sort_in(begin, len);
+  }
+
+  /** @This function performs radix-sort on array.
+      Specified radix bit width is used. */
+  template <typename X, size_t bits>
+  void radix_sort(X *begin, X *end)
+  {
+    typedef X type;
+    size_t len = end - begin;
+
+    _radix_sort<type, bits>::sort_in(begin, len);
+  }
+
+  /** @This function performs radix-sort on array. Radix
+      width is 8 bits. */
+  template <typename X>
+  void radix_sort(const X *begin, const X *end, X *out)
+  {
+    typedef X type;
+    size_t len = end - begin;
+
+    _radix_sort<type, 8>::sort_out(begin, out, len);
+  }
+
+  /** @This function performs radix-sort on array.
+      Specified radix bit width is used. */
+  template <typename X, size_t bits>
+  void radix_sort(const X *begin, const X *end, X *out)
+  {
+    typedef X type;
+    size_t len = end - begin;
+
+    _radix_sort<type, bits>::sort_out(begin, out, len);
+  }
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/ref
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/ref	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/ref	(revision 283)
@@ -0,0 +1,801 @@
+/* -*- c++ -*-
+
+   C++ smart pointer classes
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2008-2011 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_REFS_HH_
+#define DPP_REFS_HH_
+
+#include <cassert>
+#include <cstdlib>
+#include <typeinfo>
+
+/** @file @module{Smart pointer} */
+
+// #define _DPP_USE_GCC_ATOMIC
+
+namespace dpp {
+
+  template <class X> class ref;
+  template <class X> class const_ref;
+  template <class X> class clone_ref;
+  template <class X, bool clonable> class ref_base;
+
+  /** @internal 
+      @module{Smart pointer}
+  */
+  template <class X, /* object type with optional constness */
+	    class Xnoconst /* bare object type */ >
+  class ref_
+  {
+    template <class, class> friend class ref_;
+    template <class> friend class ref;
+    template <class> friend class const_ref;
+    template <class> friend class clone_ref;
+
+/** @deprecated
+    Dynamically allocate and construct object of given type with passed
+    constructor arguments.
+*/
+#define DPP_REFNEW(type, ...)			\
+    (dpp::ref<type>::create(__VA_ARGS__))
+
+  public:
+    /** @This set the internal pointer to 0. */
+    void invalidate()
+    {
+      if (_obj)
+	_drop();
+      _obj = 0;
+    }
+
+    /** @This tests if @ref ref points to a valid object. */
+    bool valid() const
+    {
+      return _obj != 0;
+    }
+
+    X & operator*() const
+    {
+      assert(_obj);
+      return *_obj;
+    }
+
+    X * operator->() const
+    {
+      assert(_obj);
+      return _obj;
+    }
+
+    /** @This returns ref internal object pointer */
+    X * ptr() const
+    {
+      return _obj;
+    }
+
+    /** @This returns object references count */
+    int count() const
+    {
+      return _obj ? _obj->_ref_count : 0;
+    }
+
+    /** @This tests if pointed objects are the same */
+    bool operator==(const ref_ &r) const
+    {
+      return _obj == r._obj;
+    }
+
+    /** @This tests if pointed objects are not the same */
+    bool operator!=(const ref_ &r) const
+    {
+      return _obj != r._obj;
+    }
+
+    /** @This tests if pointed objects are the same */
+    bool operator==(const X *p) const
+    {
+      return _obj == p;
+    }
+
+    /** @This tests if pointed objects are the same */
+    bool operator!=(const X *p) const
+    {
+      return _obj != p;
+    }
+
+    /** @This returns a @ref ref to a new dynamically allocated copy
+	of object. Object is deep copyed, new object has the same
+	derived type as source object.
+
+	While this is not need for objects dynamically allocated with
+	the @ref ref::create function, other objects have to call the
+	@ref ref_base::set_clone function from their constructor to
+	make the @ref clone function work.
+
+	The @ref clone_ref class can be used for automatic cloning on
+	smart pointer copy.
+
+	@example test/test_ref.cc:clone
+    */
+    ref<Xnoconst> clone() const
+    {
+      if (!_obj)
+	return ref<Xnoconst>();
+      return ref<Xnoconst>(_obj->template _clone<Xnoconst>());
+    }
+
+  private:
+
+    /** @internal */
+    void assign(const X &r)
+    {
+      if (_obj)
+	_drop();
+      _obj = &r;
+      if (_obj)
+	_inc();
+    }
+
+    /** @internal */
+    void assign(const ref_ &r)
+    {
+      if (_obj)
+	_drop();
+      _obj = r._obj;
+      if (_obj)
+	_inc();
+    }
+
+    /** @internal */
+    void _inc() const
+    {
+      _obj->ref_inc();
+    }
+
+    /** @internal */
+    void _drop() const
+    {
+      _obj->ref_drop();
+    }
+
+    /** @internal */
+    X *_obj;
+  };
+
+
+  /** 
+      @short Smart pointer class
+      @module{Smart pointer}
+      @header dpp/ref
+      @main
+      @order 3
+
+      @This implements an object reference class, it may hold a
+      reference to objects of type @tt X which inherit from the @ref
+      ref_base class.
+
+      This class can hold references to both statically and
+      dynamically allocated objects. When the object has been
+      dynamically allocated using the @ref create function, it will be
+      destroyed when the last reference to the object is dropped.
+
+      @see {const_ref, ref_base}
+  */
+  template <class X>
+  class ref : public ref_<X, X>
+  {
+    template <class, class> friend class ref_;
+    template <class> friend class ref;
+    template <class> friend class clone_ref;
+    typedef ref_<X, X> base;
+
+    explicit ref(X * obj)
+    {
+      base::_obj = obj;
+    }
+
+  public:
+
+    /** @multiple
+	@This dynamically allocates and construct object. Parameters
+	are passed to constructor. */
+    static ref create()
+    {
+      X *obj = new X();
+      obj->template _set_clone<X>();
+      obj->_dynamic = true;
+      obj->_ref_count = 1;
+      return ref(obj);
+    }
+
+    template <typename A0>
+    static ref create(const A0 &a0)
+    {
+      X *obj = new X(a0);
+      obj->template _set_clone<X>();
+      obj->_dynamic = true;
+      obj->_ref_count = 1;
+      return ref(obj);
+    }
+
+    template <typename A0, typename A1>
+    static ref create(const A0 &a0, const A1 &a1)
+    {
+      X *obj = new X(a0, a1);
+      obj->template _set_clone<X>();
+      obj->_dynamic = true;
+      obj->_ref_count = 1;
+      return ref(obj);
+    }
+
+    template <typename A0, typename A1, typename A2>
+    static ref create(const A0 &a0, const A1 &a1, const A2 &a2)
+    {
+      X *obj = new X(a0, a1, a2);
+      obj->template _set_clone<X>();
+      obj->_dynamic = true;
+      obj->_ref_count = 1;
+      return ref(obj);
+    }
+
+    template <typename A0, typename A1, typename A2,
+	      typename A3>
+    static ref create(const A0 &a0, const A1 &a1, const A2 &a2,
+		      const A3 &a3)
+    {
+      X *obj = new X(a0, a1, a2, a3);
+      obj->template _set_clone<X>();
+      obj->_dynamic = true;
+      obj->_ref_count = 1;
+      return ref(obj);
+    }
+
+    template <typename A0, typename A1, typename A2,
+	      typename A3, typename A4>
+    static ref create(const A0 &a0, const A1 &a1, const A2 &a2,
+		      const A3 &a3, const A4 &a4)
+    {
+      X *obj = new X(a0, a1, a2, a3, a4);
+      obj->template _set_clone<X>();
+      obj->_dynamic = true;
+      obj->_ref_count = 1;
+      return ref(obj);
+    }
+
+    template <typename A0, typename A1, typename A2,
+	      typename A3, typename A4, typename A5>
+    static ref create(const A0 &a0, const A1 &a1, const A2 &a2,
+		      const A3 &a3, const A4 &a4, const A5 &a5)
+    {
+      X *obj = new X(a0, a1, a2, a3, a4, a5);
+      obj->template _set_clone<X>();
+      obj->_dynamic = true;
+      obj->_ref_count = 1;
+      return ref(obj);
+    }
+
+    /** @This performs a dynamic cast to @ref ref of given type */
+    template <class T>
+    ref<T> dynamiccast() const
+    {
+      T *r = dynamic_cast<T*>(base::_obj);
+      if (r)
+	base::_inc();
+      return ref<T>(r);
+    }
+
+    /** @This performs a static cast to @ref ref of given type */
+    template <class T>
+    ref<T> staticcast() const
+    {
+      if (base::_obj)
+	base::_inc();
+      return ref<T>(static_cast<T*>(base::_obj));
+    }
+
+    /** Construct an empty ref */
+    ref()
+    {
+      base::_obj = 0;
+    }
+
+    /** Construct ref from ref */
+    ref(const ref &r)
+    {
+      if ((base::_obj = r._obj))
+	base::_inc();
+    }
+
+    /** Construct ref from derived class ref */
+    template <class T>
+    ref(const ref_<T, T> &r)
+    {
+      if ((base::_obj = r._obj))
+	base::_inc();
+    }
+
+    /** Construct ref from object reference */
+    ref(X &obj)
+    {
+      base::_obj = &obj;
+      base::_inc();
+    }
+
+    /** Drop a ref */
+    ~ref()
+    {
+      if (base::_obj)
+	base::_drop();
+    }
+
+    /** Initialize ref from ref */
+    ref & operator=(const ref &r)
+    {
+      base::assign(r);
+      return *this;
+    }
+
+    /** Initialize ref from object reference */
+    ref & operator=(X & obj)
+    {
+      base::assign(obj);
+      return *this;
+    }
+
+  };
+
+  /** 
+      @short Const smart pointer class
+      @module{Smart pointer}
+      @header dpp/ref
+      @main
+      @order 2
+
+      @This class is the same as the @ref ref class but hold a @b
+      const pointer to the object.
+
+      @see {ref, ref_base}
+  */
+  template <class X>
+  class const_ref : public ref_<const X, X>
+  {
+    template <class, class> friend class ref_;
+    typedef ref_<const X, X> base;
+
+    explicit const_ref(const X * obj)
+    {
+      base::_obj = obj;
+    }
+
+  public:
+
+    /** Construct an empty ref */
+    const_ref()
+    {
+      base::_obj = 0;
+    }
+
+    /** Construct const ref from const ref */
+    const_ref(const const_ref &r)
+    {
+      if ((base::_obj = r._obj))
+	base::_inc();
+    }
+
+    /** Construct const ref from derived class ref */
+    template <class T>
+    const_ref(const ref_<T, T> &r)
+    {
+      if ((base::_obj = r._obj))
+	base::_inc();
+    }
+
+    /** Construct const ref from derived class const ref */
+    template <class T>
+    const_ref(const ref_<const T, T> &r)
+    {
+      if ((base::_obj = r._obj))
+	base::_inc();
+    }
+
+    /** Construct ref from const object reference */
+    const_ref(const X &obj)
+    {
+      base::_obj = &obj;
+      base::_inc();
+    }
+
+    /** Drop a ref */
+    ~const_ref()
+    {
+      if (base::_obj)
+	base::_drop();
+    }
+
+    /** @This performs a dynamic cast to @ref const_ref of given type */
+    template <class T>
+    const_ref<T> dynamiccast() const
+    {
+      const T *r = dynamic_cast<const T*>(base::_obj);
+      if (r)
+	base::_inc();
+      return const_ref<T>(r);
+    }
+
+    /** @This performs a static cast to @ref const_ref of given type */
+    template <class T>
+    const_ref<T> staticcast() const
+    {
+      if (base::_obj)
+	base::_inc();
+      return const_ref<T>(static_cast<const T*>(base::_obj));
+    }
+
+    /** Initialize const ref from const ref */
+    const_ref & operator=(const const_ref &r)
+    {
+      base::assign(r);
+      return *this;
+    }
+
+    /** Initialize ref from object reference */
+    const_ref & operator=(const X & obj)
+    {
+      base::assign(obj);
+      return *this;
+    }
+
+  };
+
+  /** 
+      @short Automatic cloning smart pointer class
+      @module{Smart pointer}
+      @header dpp/ref
+      @main
+      @order 1
+
+      @This implements a special kind of smart pointer which clones the
+      pointed object when copied. It is intended to be used for class
+      members when the expected behavior is to clone the pointed
+      object along with the reference holder object.
+
+      The copy constructor and copy assignment operator will clone the
+      associated object instead of just copying the
+      pointer. Constructors and assignment operators which take other
+      kind of references don't perform clone.
+
+      @example test/test_ref.cc:clone1
+
+      @see {ref, ref_base}
+  */
+  template <class X>
+  class clone_ref : public ref_<X, X>
+  {
+    template <class, class> friend class ref_;
+    typedef ref_<X, X> base;
+
+  public:
+
+    /** Construct an empty ref */
+    clone_ref()
+    {
+      base::_obj = 0;
+    }
+
+    /** Construct ref from derived class ref */
+    template <class T>
+    clone_ref(const ref_<T, T> &r)
+    {
+      base::_obj = r._obj;
+      if (base::_obj)
+	base::_inc();
+    }
+
+    /** Construct clone_ref and clone pointed object */
+    clone_ref(const clone_ref &r)
+    {
+      base::_obj = r._obj ? r._obj->template _clone<X>() : 0;
+    }
+
+    /** Construct clone_ref and clone pointed object */
+    template <class T>
+    clone_ref(const clone_ref &r)
+    {
+      base::_obj = r._obj ? r._obj->template _clone<X>() : 0;
+    }
+
+    /** Construct clone_ref from object reference */
+    clone_ref(X &obj)
+    {
+      base::_obj = &obj;
+      base::_inc();
+    }
+
+    /** Drop a clone_ref */
+    ~clone_ref()
+    {
+      if (base::_obj)
+	base::_drop();
+    }
+
+    /** @This performs a dynamic cast to @ref ref of given type */
+    template <class T>
+    ref<T> dynamiccast() const
+    {
+      T *r = dynamic_cast<T*>(base::_obj);
+      if (r)
+	base::_inc();
+      return ref<T>(r);
+    }
+
+    /** @This performs a static cast to @ref ref of given type */
+    template <class T>
+    ref<T> staticcast() const
+    {
+      if (base::_obj)
+	base::_inc();
+      return ref<T>(static_cast<T*>(base::_obj));
+    }
+
+    /** Initialize clone_ref by cloning object */
+    clone_ref & operator=(const clone_ref &r)
+    {
+      if (base::_obj)
+	base::_drop();
+      base::_obj = r._obj ? r._obj->_clone() : 0;
+      return *this;
+    }
+
+    /** Initialize ref from ref */
+    clone_ref & operator=(const ref<X> &r)
+    {
+      base::assign(r);
+      return *this;
+    }
+
+    /** Initialize ref from object reference */
+    clone_ref & operator=(X & obj)
+    {
+      base::assign(obj);
+      return *this;
+    }
+
+  };
+
+  /** @internal 
+      @module{Smart pointer}
+  */
+  template <class X, bool cloneable>
+  class ref_base_
+  {
+    template <class> friend class ref;
+
+    template <class D>
+    void _set_clone()
+    {
+      /* not cloneable, no clone callback registered here */
+    }
+  };
+
+  /** @internal 
+      @module{Smart pointer}
+      This class contains cloning code.
+  */
+  template <class X>
+  class ref_base_ <X, true>
+  {
+    template <class, class> friend class ref_;
+    template <class> friend class ref;
+    template <class> friend class clone_ref;
+    template <class, bool> friend class ref_base;
+
+    ref_base_()
+      : _ref_clone(0)
+    {
+    }
+
+    /** Clone object pointed by ref */
+    template <class D>
+    D * _clone() const
+    {
+      assert(_ref_clone || !"no clone handler defined for this object");
+      return static_cast<D*>(_ref_clone(static_cast<const D*>(this)));
+    }
+
+    template <class D /* derived class */>
+    static X * _clone_hndl(const X *x)
+    {
+      assert(typeid(D) == typeid(*x) && "clone handler does not match actual object type");
+      const D * src = static_cast<const D*>(x);
+      D * obj = new D(*src);
+      obj->_ref_clone = src->_ref_clone;
+      obj->_dynamic = true;
+      obj->_ref_count = 1;
+      obj->cloned(*src);
+      return obj;
+    }
+
+    /** set specialized clone callback */
+    template <class D>
+    void _set_clone()
+    {
+      _ref_clone = &_clone_hndl<D>;
+    }
+
+    /** pointer to clone function specialized for _derived_ class */
+    X * (*_ref_clone)(const X *);
+  };
+
+  /**
+      @short Reference counting object base class
+      @module{Smart pointer}
+      @header dpp/ref
+      @showvalue
+
+      @This is the referenced object base class, any class which
+      inherits from this class can be pointed to by a @ref ref smart
+      pointer.
+
+      @tt X template parameter must be the same as inheriting class.
+
+      The @tt cloneable parameter must be set to true in order to use
+      the @ref ref::clone method. The default value is @tt false to
+      support classes with no copy constructor and optimize pointer size.
+
+      When the DPP_REF_LIVE_REFS_ASSERT macro is defined, the base
+      class destructor assert that no more live reference to the
+      object does exist.
+  */
+  template <class X, bool cloneable = false>
+  class ref_base : public ref_base_<X, cloneable>
+  {
+    template <class, class> friend class ref_;
+    template <class> friend class ref;
+    template <class> friend class const_ref;
+    template <class, bool> friend class ref_base_;
+
+  public:
+
+    ref_base()
+      : _ref_count(0),
+	_dynamic(0)
+    {
+    }
+
+    ref_base(const ref_base &r)
+      : _ref_count(0),
+	_dynamic(0)
+    {
+    }
+
+    ref_base & operator=(const ref_base &r)
+    {
+      return *this;
+    }
+
+    virtual ~ref_base()
+    {
+#ifdef DPP_REF_LIVE_REFS_ASSERT
+      assert(_ref_count == 0 || !"Can not destruct object which has live references");
+#endif
+    }
+
+    /** Setup a clone handler for this object. This function may be
+	called from derived class constructor to make objects
+	cloneable. Objects which are dynamically allocated using the
+	@ref ref::create function do not require this call. */
+    template <class Derived>
+    void set_clone()
+    {
+      ref_base_<X, cloneable>::template _set_clone<Derived>();
+    }
+
+    /** @This is called when this object has just been cloned. The
+	call is performed on most derived class (see @ref set_clone
+	function). This default implementation is empty. */
+    void cloned(const X &src)
+    {
+    }
+
+    /** @This is called when the reference counter has just been
+	increased. The call is performed on reference to @tt X class so
+	a virtual prototype must be declared in the @tt X class to
+	override this function from further derived classes.
+	This default implementation is empty.
+	@see ref_decreased @see ref_inc
+    */
+    void ref_increased(int ref_count) const
+    {
+    }
+
+    /** Same as @ref ref_increased but called when the counter has
+	been decreased. This default implementation is empty.
+	@see ref_dec
+    */
+    void ref_decreased(int ref_count) const
+    {
+    }
+
+    /** @This increases references count on object. It should only be
+	used on rare cases when smart pointer classes can not be used
+	to track all references to the object. @see ref_drop */
+    void ref_inc() const
+    {
+#ifdef _DPP_USE_GCC_ATOMIC
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+      __sync_add_and_fetch(&const_cast<ref_base*>(this)->_raw, 1);
+# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+      __sync_add_and_fetch(&const_cast<ref_base*>(this)->_raw, 2);
+# else
+#  error __BYTE_ORDER__ not defined
+# endif
+#else
+      const_cast<ref_base*>(this)->_ref_count++;
+#endif
+
+      static_cast<const X*>(this)->ref_increased(_ref_count);
+    }
+
+    /** @This decreases references count on object. Dynamically
+	allocated objects are deleted if counter reaches 0. It should
+	only be used on rare cases when smart pointer classes can not
+	be used to track all references to the object. @see ref_inc */
+    void ref_drop() const
+    {
+      assert(_ref_count > 0);
+
+#ifdef _DPP_USE_GCC_ATOMIC
+# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+      __sync_sub_and_fetch(&const_cast<ref_base*>(this)->_raw, 1);
+# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+      __sync_sub_and_fetch(&const_cast<ref_base*>(this)->_raw, 2);
+# endif
+#else
+      const_cast<ref_base*>(this)->_ref_count--;
+#endif
+
+      static_cast<const X*>(this)->ref_decreased(_ref_count);
+
+      // free dynamically allocated objects only
+      if (_dynamic && _ref_count == 0)
+	delete this;
+    }
+
+  private:
+
+    /** reference counter value */
+    union {
+      struct {
+	int _ref_count:31;
+	int _dynamic:1;
+      };
+      int _raw;
+    };
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/template_switch
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/template_switch	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/template_switch	(revision 283)
@@ -0,0 +1,428 @@
+/* -*- c++ -*-
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2012 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+   Some parts of this file were generated using tools/template_switch.pl
+
+*/
+
+#ifndef DPP_TEMPLATE_SWITCH_HH_
+#define DPP_TEMPLATE_SWITCH_HH_
+
+/** @file @module {Template switch} */
+
+namespace dpp {
+
+  /** 
+      @module {Template switch}
+      @header dpp/template_switch
+
+      @This declares a class designed to hold an array of function
+      pointers for multiple instances of the same template function
+      but with different values of its enum template parameter.
+
+      The class constructor fill the array with function pointers for
+      all enum values between 0 and @tt C0. The function pointer can
+      later be retrieved using the @tt {()} operator on the template
+      switch object.
+
+      Other classes exists which hold multidimensional array to deal
+      with multiple enum template parameters.
+
+      @section {Examples}
+      Use of template switch with global function and 1 enum parameter:
+      @example test/test_template_switch.cc:example|example1
+ 
+      Use of template switch with member function and 2 enum parameters:
+      @example test/test_template_switch.cc:example|example2
+      @end section
+  */
+#define DPP_TEMPLATE_SWITCH_1(clname, func_type, func, C0)	\
+  class clname							\
+  {								\
+    typedef typeof(C0) e0;					\
+								\
+    typedef func_type table_type[C0+1];				\
+    table_type _t;						\
+								\
+    template <int I0, bool done>				\
+    struct iter;						\
+								\
+    template <int I0>						\
+    struct iter<I0, true>					\
+    {								\
+      static void s(table_type &t)				\
+      {								\
+      }								\
+    };								\
+								\
+    template <int I0, bool done>				\
+    struct iter							\
+    {								\
+      static void s(table_type &t)				\
+      {								\
+	t[I0] = &func<(e0)I0>;					\
+        iter<2*I0+1, (2*I0+1 >= C0+1)>::s(t);			\
+        iter<2*I0+2, (2*I0+2 >= C0+1)>::s(t);			\
+      }								\
+    };								\
+								\
+  public:							\
+								\
+    clname()							\
+    {								\
+      iter<0, false>::s(_t);					\
+    }								\
+								\
+    const func_type operator() (e0 p0) const			\
+    {								\
+      return _t[p0];						\
+    }								\
+  }
+
+  /** 
+      @module {Template switch}
+      @header dpp/template_switch
+      @see #DPP_TEMPLATE_SWITCH_1
+  */
+#define DPP_TEMPLATE_SWITCH_2(clname, func_type, func, C0, C1)	\
+  class clname							\
+  {								\
+    typedef typeof(C0) e0;					\
+    typedef typeof(C1) e1;					\
+								\
+    typedef func_type table_type[C0+1][C1+1];			\
+    table_type _t;						\
+								\
+    template <int I0, int I1, bool done>			\
+    struct iter;						\
+								\
+    template <int I0, int I1>					\
+    struct iter<I0, I1, true>					\
+    {								\
+      static void s(table_type &t)				\
+      {								\
+      }								\
+    };								\
+								\
+    template <int I0, int I1, bool done>			\
+    struct iter							\
+    {								\
+      static void s(table_type &t)				\
+      {								\
+	t[I0][I1] = &func<(e0)I0, (e1)I1>;			\
+        iter<2*I0+1, I1, (2*I0+1 >= C0+1)>::s(t);		\
+        iter<2*I0+2, I1, (2*I0+2 >= C0+1)>::s(t);		\
+        if (2*I0+1 == C0+1 || 2*I0+2 == C0+1) {			\
+          iter<0, 2*I1+1, (2*I1+1 >= C1+1)>::s(t);		\
+          iter<0, 2*I1+2, (2*I1+2 >= C1+1)>::s(t);		\
+        }							\
+      }								\
+    };								\
+								\
+  public:							\
+								\
+    clname()							\
+    {								\
+      iter<0, 0, false>::s(_t);					\
+    }								\
+								\
+    const func_type operator() (e0 p0, e1 p1) const		\
+    {								\
+      return _t[p0][p1];					\
+    }								\
+  }
+
+
+  /** 
+      @module {Template switch}
+      @header dpp/template_switch
+      @see #DPP_TEMPLATE_SWITCH_1
+  */
+#define DPP_TEMPLATE_SWITCH_3(clname, func_type, func,		\
+			      C0, C1, C2)			\
+  class clname							\
+  {								\
+    typedef typeof(C0) e0;					\
+    typedef typeof(C1) e1;					\
+    typedef typeof(C2) e2;					\
+								\
+    typedef func_type table_type[C0+1][C1+1][C2+1];		\
+    table_type _t;						\
+								\
+    template <int I0, int I1, int I2, bool done>		\
+    struct iter;						\
+								\
+    template <int I0, int I1, int I2>				\
+    struct iter<I0, I1, I2, true>				\
+    {								\
+      static void s(table_type &t)				\
+      {								\
+      }								\
+    };								\
+								\
+    template <int I0, int I1, int I2, bool done>		\
+    struct iter							\
+    {								\
+      static void s(table_type &t)				\
+      {								\
+	t[I0][I1][I2] = &func<(e0)I0, (e1)I1, (e2)I2>;		\
+        iter<2*I0+1, I1, I2, (2*I0+1 >= C0+1)>::s(t);		\
+        iter<2*I0+2, I1, I2, (2*I0+2 >= C0+1)>::s(t);		\
+        if (2*I0+1 == C0+1 || 2*I0+2 == C0+1) {			\
+          iter<0, 2*I1+1, I2, (2*I1+1 >= C1+1)>::s(t);		\
+          iter<0, 2*I1+2, I2, (2*I1+2 >= C1+1)>::s(t);		\
+          if (2*I1+1 == C1+1 || 2*I1+2 == C1+1) {		\
+            iter<0, 0, 2*I2+1, (2*I2+1 >= C2+1)>::s(t);		\
+            iter<0, 0, 2*I2+2, (2*I2+2 >= C2+1)>::s(t);		\
+          }							\
+        }							\
+      }								\
+    };								\
+								\
+  public:							\
+								\
+    clname()							\
+    {								\
+      iter<0, 0, 0, false>::s(_t);				\
+    }								\
+								\
+    const func_type operator() (e0 p0, e1 p1, e2 p2) const	\
+    {								\
+      return _t[p0][p1][p2];					\
+    }								\
+  }
+
+
+  /** 
+      @module {Template switch}
+      @header dpp/template_switch
+      @see #DPP_TEMPLATE_SWITCH_1
+  */
+#define DPP_TEMPLATE_SWITCH_4(clname, func_type, func,			\
+			      C0, C1, C2, C3)				\
+  class clname								\
+  {									\
+    typedef typeof(C0) e0;						\
+    typedef typeof(C1) e1;						\
+    typedef typeof(C2) e2;						\
+    typedef typeof(C3) e3;						\
+									\
+    typedef func_type table_type[C0+1][C1+1][C2+1][C3+1];		\
+    table_type _t;							\
+									\
+    template <int I0, int I1, int I2, int I3, bool done>		\
+    struct iter;							\
+									\
+    template <int I0, int I1, int I2, int I3>				\
+    struct iter<I0, I1, I2, I3, true>					\
+    {									\
+      static void s(table_type &t)					\
+      {									\
+      }									\
+    };									\
+									\
+    template <int I0, int I1, int I2, int I3, bool done>		\
+    struct iter								\
+    {									\
+      static void s(table_type &t)					\
+      {									\
+	t[I0][I1][I2][I3] = &func<(e0)I0, (e1)I1, (e2)I2, (e3)I3>;	\
+        iter<2*I0+1, I1, I2, I3, (2*I0+1 >= C0+1)>::s(t);		\
+        iter<2*I0+2, I1, I2, I3, (2*I0+2 >= C0+1)>::s(t);		\
+        if (2*I0+1 == C0+1 || 2*I0+2 == C0+1) {				\
+          iter<0, 2*I1+1, I2, I3, (2*I1+1 >= C1+1)>::s(t);		\
+          iter<0, 2*I1+2, I2, I3, (2*I1+2 >= C1+1)>::s(t);		\
+          if (2*I1+1 == C1+1 || 2*I1+2 == C1+1) {			\
+            iter<0, 0, 2*I2+1, I3, (2*I2+1 >= C2+1)>::s(t);		\
+            iter<0, 0, 2*I2+2, I3, (2*I2+2 >= C2+1)>::s(t);		\
+            if (2*I2+1 == C2+1 || 2*I2+2 == C2+1) {			\
+              iter<0, 0, 0, 2*I3+1, (2*I3+1 >= C3+1)>::s(t);		\
+              iter<0, 0, 0, 2*I3+2, (2*I3+2 >= C3+1)>::s(t);		\
+            }								\
+          }								\
+        }								\
+      }									\
+    };									\
+									\
+  public:								\
+									\
+    clname()								\
+    {									\
+      iter<0, 0, 0, 0, false>::s(_t);					\
+    }									\
+									\
+    const func_type operator() (e0 p0, e1 p1, e2 p2, e3 p3) const	\
+    {									\
+      return _t[p0][p1][p2][p3];					\
+    }									\
+  }
+
+
+  /** 
+      @module {Template switch}
+      @header dpp/template_switch
+      @see #DPP_TEMPLATE_SWITCH_1
+  */
+#define DPP_TEMPLATE_SWITCH_5(clname, func_type, func,			\
+			      C0, C1, C2, C3, C4)			\
+  class clname								\
+  {									\
+    typedef typeof(C0) e0;						\
+    typedef typeof(C1) e1;						\
+    typedef typeof(C2) e2;						\
+    typedef typeof(C3) e3;						\
+    typedef typeof(C4) e4;						\
+									\
+    typedef func_type table_type[C0+1][C1+1][C2+1][C3+1][C4+1];		\
+    table_type _t;							\
+									\
+    template <int I0, int I1, int I2, int I3, int I4, bool done>	\
+    struct iter;							\
+									\
+    template <int I0, int I1, int I2, int I3, int I4>			\
+    struct iter<I0, I1, I2, I3, I4, true>				\
+    {									\
+      static void s(table_type &t)					\
+      {									\
+      }									\
+    };									\
+									\
+    template <int I0, int I1, int I2, int I3, int I4, bool done>	\
+    struct iter								\
+    {									\
+      static void s(table_type &t)					\
+      {									\
+	t[I0][I1][I2][I3][I4] = &func<(e0)I0, (e1)I1, (e2)I2, (e3)I3, (e4)I4>; \
+        iter<2*I0+1, I1, I2, I3, I4, (2*I0+1 >= C0+1)>::s(t);		\
+        iter<2*I0+2, I1, I2, I3, I4, (2*I0+2 >= C0+1)>::s(t);		\
+        if (2*I0+1 == C0+1 || 2*I0+2 == C0+1) {				\
+          iter<0, 2*I1+1, I2, I3, I4, (2*I1+1 >= C1+1)>::s(t);		\
+          iter<0, 2*I1+2, I2, I3, I4, (2*I1+2 >= C1+1)>::s(t);		\
+          if (2*I1+1 == C1+1 || 2*I1+2 == C1+1) {			\
+            iter<0, 0, 2*I2+1, I3, I4, (2*I2+1 >= C2+1)>::s(t);		\
+            iter<0, 0, 2*I2+2, I3, I4, (2*I2+2 >= C2+1)>::s(t);		\
+            if (2*I2+1 == C2+1 || 2*I2+2 == C2+1) {			\
+              iter<0, 0, 0, 2*I3+1, I4, (2*I3+1 >= C3+1)>::s(t);	\
+              iter<0, 0, 0, 2*I3+2, I4, (2*I3+2 >= C3+1)>::s(t);	\
+              if (2*I3+1 == C3+1 || 2*I3+2 == C3+1) {			\
+                iter<0, 0, 0, 0, 2*I4+1, (2*I4+1 >= C4+1)>::s(t);	\
+                iter<0, 0, 0, 0, 2*I4+2, (2*I4+2 >= C4+1)>::s(t);	\
+              }								\
+            }								\
+          }								\
+        }								\
+      }									\
+    };									\
+									\
+  public:								\
+									\
+    clname()								\
+    {									\
+      iter<0, 0, 0, 0, 0, false>::s(_t);				\
+    }									\
+									\
+    const func_type operator() (e0 p0, e1 p1, e2 p2, e3 p3, e4 p4) const \
+    {									\
+      return _t[p0][p1][p2][p3][p4];					\
+    }									\
+  }
+
+
+  /** 
+      @module {Template switch}
+      @header dpp/template_switch
+      @see #DPP_TEMPLATE_SWITCH_1
+  */
+#define DPP_TEMPLATE_SWITCH_6(clname, func_type, func,			\
+			      C0, C1, C2, C3, C4, C5)			\
+  class clname								\
+  {									\
+    typedef typeof(C0) e0;						\
+    typedef typeof(C1) e1;						\
+    typedef typeof(C2) e2;						\
+    typedef typeof(C3) e3;						\
+    typedef typeof(C4) e4;						\
+    typedef typeof(C5) e5;						\
+									\
+    typedef func_type table_type[C0+1][C1+1][C2+1][C3+1][C4+1][C5+1];	\
+    table_type _t;							\
+									\
+    template <int I0, int I1, int I2, int I3, int I4, int I5, bool done> \
+    struct iter;							\
+									\
+    template <int I0, int I1, int I2, int I3, int I4, int I5>		\
+    struct iter<I0, I1, I2, I3, I4, I5, true>				\
+    {									\
+      static void s(table_type &t)					\
+      {									\
+      }									\
+    };									\
+									\
+    template <int I0, int I1, int I2, int I3, int I4, int I5, bool done> \
+    struct iter								\
+    {									\
+      static void s(table_type &t)					\
+      {									\
+	t[I0][I1][I2][I3][I4][I5] = &func<(e0)I0, (e1)I1, (e2)I2, (e3)I3, (e4)I4, (e5)I5>; \
+        iter<2*I0+1, I1, I2, I3, I4, I5, (2*I0+1 >= C0+1)>::s(t);	\
+        iter<2*I0+2, I1, I2, I3, I4, I5, (2*I0+2 >= C0+1)>::s(t);	\
+        if (2*I0+1 == C0+1 || 2*I0+2 == C0+1) {				\
+          iter<0, 2*I1+1, I2, I3, I4, I5, (2*I1+1 >= C1+1)>::s(t);	\
+          iter<0, 2*I1+2, I2, I3, I4, I5, (2*I1+2 >= C1+1)>::s(t);	\
+          if (2*I1+1 == C1+1 || 2*I1+2 == C1+1) {			\
+            iter<0, 0, 2*I2+1, I3, I4, I5, (2*I2+1 >= C2+1)>::s(t);	\
+            iter<0, 0, 2*I2+2, I3, I4, I5, (2*I2+2 >= C2+1)>::s(t);	\
+            if (2*I2+1 == C2+1 || 2*I2+2 == C2+1) {			\
+              iter<0, 0, 0, 2*I3+1, I4, I5, (2*I3+1 >= C3+1)>::s(t);	\
+              iter<0, 0, 0, 2*I3+2, I4, I5, (2*I3+2 >= C3+1)>::s(t);	\
+              if (2*I3+1 == C3+1 || 2*I3+2 == C3+1) {			\
+                iter<0, 0, 0, 0, 2*I4+1, I5, (2*I4+1 >= C4+1)>::s(t);	\
+                iter<0, 0, 0, 0, 2*I4+2, I5, (2*I4+2 >= C4+1)>::s(t);	\
+                if (2*I4+1 == C4+1 || 2*I4+2 == C4+1) {			\
+                  iter<0, 0, 0, 0, 0, 2*I5+1, (2*I5+1 >= C5+1)>::s(t);	\
+                  iter<0, 0, 0, 0, 0, 2*I5+2, (2*I5+2 >= C5+1)>::s(t);	\
+                }							\
+              }								\
+            }								\
+          }								\
+        }								\
+      }									\
+    };									\
+									\
+  public:								\
+									\
+    clname()								\
+    {									\
+      iter<0, 0, 0, 0, 0, 0, false>::s(_t);				\
+    }									\
+									\
+    const func_type operator() (e0 p0, e1 p1, e2 p2, e3 p3, e4 p4, e5 p5) const	\
+    {									\
+      return _t[p0][p1][p2][p3][p4][p5];				\
+    }									\
+  }
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/vector_pool
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/vector_pool	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/vector_pool	(revision 283)
@@ -0,0 +1,550 @@
+/* -*- c++ -*-
+
+   C++ Indexable objects pool
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2010 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_VECTOR_POOL_HH_
+#define DPP_VECTOR_POOL_HH_
+
+#include <stdexcept>
+#include <memory>
+#include <vector>
+
+/** @file @module{Vector pool} */
+
+namespace dpp {
+
+  template <class X, unsigned int block_size = 32,
+            class Allocator = std::allocator<X>,
+	    class PtrAllocator = std::allocator<X*> >
+  class vector_pool;
+
+  /** @short Vector pool iterator class
+      @module {Vector pool}
+      @header dpp/vector_pool
+      @internal
+
+      @This contains the iterator implementation for the @ref
+      vector_pool class.
+   */
+  template <typename P, typename E, int direction>         /* FIXME rework iterator (more ops, copy, const, ...) */
+  class vector_pool_iterator
+  {
+    template <class, unsigned int, class, class> friend class vector_pool;
+    template <class, class, int> friend class vector_pool_iterator;
+
+    P *_pool;
+    unsigned int _i;
+
+    vector_pool_iterator (P *pool, unsigned int i)
+      : _pool(pool),
+	_i(i)
+    {
+    }
+
+  public:
+
+    typedef typename P::value_type value_type;
+    typedef typename P::reference reference;
+    typedef typename P::const_reference const_reference;
+    typedef typename P::pointer pointer;
+    typedef typename P::const_pointer const_pointer;
+    typedef unsigned int size_type;
+    typedef int difference_type;
+
+    typedef std::bidirectional_iterator_tag iterator_category;
+
+    vector_pool_iterator()
+    {
+    }
+
+    template <class P_, class E_>
+    vector_pool_iterator(const vector_pool_iterator<P_, E_, direction> &i)
+      : _pool(i._pool),
+	_i(i._i)
+    {
+    }
+
+    inline E & operator*()
+    {
+      return (*_pool)[_i];
+    }
+
+    inline E * operator->()
+    {
+      return &(*_pool)[_i];
+    }
+
+    inline vector_pool_iterator & operator++()
+    {
+      _i += direction;
+      return *this;
+    }
+
+    inline vector_pool_iterator operator++(int)
+    {
+      vector_pool_iterator tmp(*this);
+      _i += direction;
+      return tmp;
+    }
+
+    inline vector_pool_iterator & operator--()
+    {
+      _i -= direction;
+      return *this;
+    }
+
+    inline vector_pool_iterator operator--(int)
+    {
+      vector_pool_iterator tmp(*this);
+      _i -= direction;
+      return tmp;
+    }
+
+    vector_pool_iterator operator-(int x) const
+    {
+      return vector_pool_iterator(_pool, _i - x * direction);
+    }
+
+    vector_pool_iterator operator+(int x) const
+    {
+      return vector_pool_iterator(_pool, _i + x * direction);
+    }
+
+    difference_type operator-(const vector_pool_iterator & i) const
+    {
+      return (_i - i._i) * direction;
+    }
+
+    inline bool operator<(const vector_pool_iterator &i) const
+    {
+      return _i < i._i;
+    }
+
+    inline bool operator==(const vector_pool_iterator &i) const
+    {
+      return _i == i._i;
+    }
+
+    inline bool operator!=(const vector_pool_iterator &i) const
+    {
+      return _i != i._i;
+    }
+  };
+
+
+  /** @short Indexable allocation pool
+      @module {Vector pool}
+      @header dpp/vector_pool
+      @main
+      @showvalue
+
+      This class provides an indexable object allocation pool.  The
+      pool can be accessed and traversed like a @ref std::vector.
+      Only the last or all objects in pool can be removed at once.
+
+      The @ref create functions must be used to allocate and construct
+      objects in pool. Unlike @ref std::vector this class does not
+      require assignment operator to be available in the object class.
+
+      The pool allocates storage blocks for multiple objects at once.
+      The number of objects in a storage block can be specified as
+      template parameter. Moreover a static storage space can be
+      provided for first storage blocks when creating the pool.
+
+      Unlike @ref std::vector, iterators and pointers to objects in
+      the pool are not invalidated by allocation and elements in the
+      pool are not stored at contiguous locations when crossing the @tt
+      block_size boundary.
+
+      The @tt Allocator and @tt PtrAllocator standard allocators
+      parameters are used to allocate objects and manage vector of
+      storage blocks respectively.
+  */
+  template <class X, unsigned int block_size,
+	    class Allocator, class PtrAllocator>
+  class vector_pool
+  {
+    vector_pool(const vector_pool &);
+    const vector_pool & operator= (const vector_pool &);
+
+    typedef std::vector<X *, PtrAllocator> block_list_t;
+
+    block_list_t	_blocks;
+    size_t		_free_count;
+    size_t		_static_size;
+    Allocator		_allocator;
+
+    X * get_ptr(unsigned int i) const
+    {
+      return _blocks[i / block_size] + i % block_size;
+    }
+
+    X *alloc(size_t count = 1)
+    {
+      while (_free_count < count)
+	add_block();
+
+      unsigned int id = _blocks.size() * block_size - _free_count;
+      _free_count -= count;
+
+      return get_ptr(id);
+    }
+
+    void add_block()
+    {
+      const void *hint = _blocks.empty() ? 0 : (const void*)_blocks.front();
+      X *b = (X*)_allocator.allocate(block_size, hint);
+
+      _free_count += block_size;
+      _blocks.push_back(b);
+    }
+
+  public:
+
+    typedef X value_type;
+    typedef X & reference;
+    typedef const X & const_reference;
+    typedef X * pointer;
+    typedef const X * const_pointer;
+    typedef unsigned int size_type;
+    typedef int difference_type;
+    typedef Allocator allocator_type;
+
+    typedef vector_pool_iterator<vector_pool<X, block_size>, X, 1 > iterator;
+    typedef vector_pool_iterator<const vector_pool<X, block_size>, const X, 1 > const_iterator;
+    typedef vector_pool_iterator<vector_pool<X, block_size>, X, -1 > reverse_iterator;
+    typedef vector_pool_iterator<const vector_pool<X, block_size>, const X, -1 > const_reverse_iterator;
+
+    /** Storage space for a single block of objects in pool */
+    typedef unsigned char block_type[sizeof(X) * block_size];
+
+    /** @This creates a new pool with empty storage. */
+     vector_pool(const Allocator &a = Allocator(),
+		 const PtrAllocator &pa = PtrAllocator())
+      : _blocks(pa),
+	_free_count(0),
+	_static_size(0),
+	_allocator(a)
+    {
+    }
+
+    /** @This creates a new pool and provide static storage space for
+	the first block. */
+    vector_pool(block_type &first,
+		const Allocator &a = Allocator(),
+		const PtrAllocator &pa = PtrAllocator())
+      : _blocks(pa),
+	_free_count(block_size),
+	_static_size(1),
+	_allocator(a)
+    {
+      _blocks.push_back((X*)first);
+    }
+
+    /** @This creates a new pool and provide static storage space for
+	multiple blocks. */
+    vector_pool(block_type block[], size_t count,
+		const Allocator &a = Allocator(),
+		const PtrAllocator &pa = PtrAllocator())
+      : _blocks(pa),
+	_free_count(block_size * count),
+	_static_size(count),
+	_allocator(a)
+    {
+      for (unsigned int i = 0; i < count; i++)
+	_blocks.push_back((X*)block[i]);
+    }
+
+    /** @This destroy pool along with contained objects */
+    ~vector_pool()
+    {
+      clear();
+      shrink();
+    }
+
+    /** @This returns reference to object at given position in pool */
+    const X & operator[](unsigned int i) const
+    {
+      return *get_ptr(i);
+    }
+
+    /** @This returns reference to object at given position in pool */
+    X & operator[](unsigned int i)
+    {
+      return *get_ptr(i);
+    }
+
+    /** @This returns reference to object at given position in pool
+	with bound checking */
+    const X & at(unsigned int i) const throw (std::out_of_range)
+    {
+      if (i >= size())
+	throw std::out_of_range("vector_pool access out of bounds");
+      return *get_ptr(i);
+    }
+
+    /** @This returns reference to object at given position in pool
+	with bound checking */
+    X & at(unsigned int i) throw (std::out_of_range)
+    {
+      if (i >= size())
+	throw std::out_of_range("vector_pool access out of bounds");
+      return *get_ptr(i);
+    }
+
+    /** @This allocates and construct a new object in pool */
+    X &create()
+    {
+      return *new(alloc())X();
+    }
+
+    X * create_array(size_t count)
+    {
+      X *t = alloc(count);
+      for (unsigned int i = 0; i < count; i++)
+	new(t + i)X();
+      return t;
+    }
+
+#define _DPP_VECTOR_POOL_CREATE(a, b, ...)		\
+    template <__VA_ARGS__>				\
+    inline X &create a					\
+    {							\
+      return *new(alloc())X b;				\
+    }
+
+#define _DPP_VECTOR_POOL_CREATE_ARRAY(a, b, ...)	\
+    template <__VA_ARGS__>				\
+    inline X * create_array a				\
+    {							\
+      X *t = alloc(count);				\
+      for (unsigned int i = 0; i < count; i++)		\
+	new(t + i)X b;					\
+      return t;						\
+    }
+
+    /** @multiple
+	@This allocates and construct a new object in pool. Parameters
+	are passed to constructor. */
+
+    _DPP_VECTOR_POOL_CREATE((const P1 &p1), (p1), typename P1);
+
+    _DPP_VECTOR_POOL_CREATE((const P1 &p1, const P2 &p2), (p1, p2), typename P1, typename P2);
+
+    _DPP_VECTOR_POOL_CREATE((const P1 &p1, const P2 &p2, const P3 &p3), (p1, p2, p3),
+			    typename P1, typename P2, typename P3);
+
+    _DPP_VECTOR_POOL_CREATE((const P1 &p1, const P2 &p2, const P3 &p3,
+			     const P4 &p4),
+			    (p1, p2, p3, p4),
+			    typename P1, typename P2, typename P3,
+			    typename P4);
+
+    _DPP_VECTOR_POOL_CREATE((const P1 &p1, const P2 &p2, const P3 &p3,
+			     const P4 &p4, const P5 &p5),
+			    (p1, p2, p3, p4, p5),
+			    typename P1, typename P2, typename P3,
+			    typename P4, typename P5);
+
+    _DPP_VECTOR_POOL_CREATE((const P1 &p1, const P2 &p2, const P3 &p3,
+			     const P4 &p4, const P5 &p5, const P6 &p6),
+			    (p1, p2, p3, p4, p5, p6),
+			    typename P1, typename P2, typename P3,
+			    typename P4, typename P5, typename P6);
+
+    /** @multiple
+	@This allocates and construct multiple objects in pool. Parameters
+	are passed to constructor. */
+
+    _DPP_VECTOR_POOL_CREATE_ARRAY((size_t count, const P1 &p1), (p1), typename P1);
+
+    _DPP_VECTOR_POOL_CREATE_ARRAY((size_t count, const P1 &p1, const P2 &p2), (p1, p2), typename P1, typename P2);
+
+    _DPP_VECTOR_POOL_CREATE_ARRAY((size_t count, const P1 &p1, const P2 &p2, const P3 &p3), (p1, p2, p3),
+			    typename P1, typename P2, typename P3);
+
+    _DPP_VECTOR_POOL_CREATE_ARRAY((size_t count, const P1 &p1, const P2 &p2, const P3 &p3,
+			     const P4 &p4),
+			    (p1, p2, p3, p4),
+			    typename P1, typename P2, typename P3,
+			    typename P4);
+
+    _DPP_VECTOR_POOL_CREATE_ARRAY((size_t count, const P1 &p1, const P2 &p2, const P3 &p3,
+			     const P4 &p4, const P5 &p5),
+			    (p1, p2, p3, p4, p5),
+			    typename P1, typename P2, typename P3,
+			    typename P4, typename P5);
+
+    _DPP_VECTOR_POOL_CREATE_ARRAY((size_t count, const P1 &p1, const P2 &p2, const P3 &p3,
+			     const P4 &p4, const P5 &p5, const P6 &p6),
+			    (p1, p2, p3, p4, p5, p6),
+			    typename P1, typename P2, typename P3,
+			    typename P4, typename P5, typename P6);
+
+    /** @This removes last entry. It does not reduce
+	allocated blocks count. @see shrink */
+    void pop_back()
+    {
+      unsigned int id = _blocks.size() * block_size - ++_free_count;
+
+      get_ptr(id)->~X();
+    }
+
+    /** @This destroys all objects in pool. It does not reduce
+	allocated blocks count. @see shrink */
+    void clear()
+    {
+      int i;
+      unsigned int j;
+
+      for (i = _blocks.size() - 1; i >= 0; i--)
+	{
+	  for (j = 0; j < block_size - _free_count % block_size; j++)
+	    _blocks[i][j].~X();
+	  _free_count += j;
+	}
+    }
+
+    /** @This frees unused storage blocks at end of pool. */
+    void shrink()
+    {
+      while (_blocks.size() > _static_size)
+	{
+	  _allocator.deallocate(_blocks.back(), block_size);
+	  _blocks.pop_back();
+	  _free_count -= block_size;
+	}
+    }
+
+    /** @This allocates enough storage blocks to hold at least @tt
+	count objects */
+    void reserve(size_t count)
+    {
+      while (capacity() < count)
+	add_block();
+    }
+
+    /** @This returns current live objects count in pool */
+    inline size_t size() const
+    {
+      return _blocks.size() * block_size - _free_count;
+    }
+
+    /** @This returns current allocated storage space in objects count unit */
+    inline size_t capacity() const
+    {
+      return _blocks.size() * block_size;
+    }
+
+    /** @This tests pool empty state */
+    inline bool empty() const
+    {
+      return size() == 0;
+    }
+
+    /** @This returns first object in pool */
+    inline const X & front() const
+    {
+      return *_blocks.front();
+    }
+
+    /** @This returns first object in pool */
+    inline X & front()
+    {
+      return *_blocks.front();
+    }
+
+    /** @This returns last object in pool */
+    inline const X & back() const
+    {
+      return *get_ptr(size() - 1);
+    }
+
+    /** @This returns last object in pool */
+    inline X & back()
+    {
+      return *get_ptr(size() - 1);
+    }
+
+    /** @This returns @ref iterator to first object in pool */
+    inline iterator begin()
+    {
+      return iterator(this, 0);
+    }
+
+    /** @This returns end @ref iterator */
+    inline iterator end()
+    {
+      return iterator(this, size());
+    }
+
+    /** @This returns @ref const_iterator to first object in pool */
+    inline const_iterator begin() const
+    {
+      return const_iterator(this, 0);	
+    }
+
+    /** @This returns end @ref const_iterator */
+    inline const_iterator end() const
+    {
+      return const_iterator(this, size());
+    }
+
+    /** @This returns @ref reverse_iterator to last object in pool */
+    inline reverse_iterator rbegin()
+    {
+      return reverse_iterator(this, size() - 1);
+    }
+
+    /** @This returns end @ref reverse_iterator */
+    inline reverse_iterator rend()
+    {
+      return reverse_iterator(this, -1);
+    }
+
+    /** @This returns @ref const_reverse_iterator to first object in pool */
+    inline const_reverse_iterator rbegin() const
+    {
+      return const_reverse_iterator(this, size() - 1);
+    }
+
+    /** @This returns end @ref const_reverse_iterator */
+    inline const_reverse_iterator rend() const
+    {
+      return const_reverse_iterator(this, -1);
+    }
+
+    /** @This returns pool object allocator */
+    const allocator_type & get_allocator() const
+    {
+      return _allocator;
+    }
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/vlarray
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/vlarray	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/vlarray	(revision 283)
@@ -0,0 +1,298 @@
+/* -*- c++ -*-
+
+   Simple C++ variable array of non-POD objects
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2011 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_VLARRAY_HH_
+#define DPP_VLARRAY_HH_
+
+#include <memory>
+#include <stdexcept>
+
+#include <stddef.h>
+#include <stdint.h>
+
+/** @file @module{Variable length array} */
+
+namespace dpp {
+
+  /** @short Variable length array iterator class
+      @module {Variable length array}
+      @header dpp/vlarray
+      @internal
+  */
+  template <typename X, int direction>
+  class vlarray_iterator
+  {
+    template <class, int> friend class vlarray_iterator;
+    template <class> friend class vlarray;
+
+    vlarray_iterator(X *vlarray, unsigned int i)
+      : _array(vlarray),
+	_i(i)
+    {
+    }
+
+  public:
+
+    typedef X value_type;
+    typedef X & reference;
+    typedef const X & const_reference;
+    typedef X * pointer;
+    typedef const X * const_pointer;
+    typedef unsigned int size_type;
+    typedef int difference_type;
+
+    typedef std::bidirectional_iterator_tag iterator_category;
+
+    vlarray_iterator()
+    {
+    }
+
+    template <class T>
+    vlarray_iterator(const vlarray_iterator<T, direction> &i)
+      : _array(i._array),
+	_i(i._i)
+    {
+    }
+
+    X & operator*()
+    {
+      return _array[_i];
+    }
+
+    X * operator->()
+    {
+      return &_array[_i];
+    }
+
+    vlarray_iterator & operator++()
+    {
+      _i += direction;
+      return *this;
+    }
+
+    vlarray_iterator operator++(int)
+    {
+      vlarray_iterator tmp(*this);
+      _i += direction;
+      return tmp;
+    }
+
+    vlarray_iterator & operator--()
+    {
+      _i -= direction;
+      return *this;
+    }
+
+    vlarray_iterator operator--(int)
+    {
+      vlarray_iterator tmp(*this);
+      _i -= direction;
+      return tmp;
+    }
+
+    vlarray_iterator operator-(int x) const
+    {
+      return vlarray_iterator(_array, _i - x * direction);
+    }
+
+    vlarray_iterator operator+(int x) const
+    {
+      return vlarray_iterator(_array, _i + x * direction);
+    }
+
+    difference_type operator-(const vlarray_iterator & i) const
+    {
+      return (_i - i._i) * direction;
+    }
+
+    bool operator<(const vlarray_iterator & i) const
+    {
+      return _i < i._i;
+    }
+
+    bool operator==(const vlarray_iterator &i) const
+    {
+      return _i == i._i;
+    }
+
+    bool operator!=(const vlarray_iterator &i) const
+    {
+      return _i != i._i;
+    }
+
+  private:
+    X *_array;
+    unsigned int _i;
+  };
+
+  /** @short Variable length array class
+      @module {Variable length array}
+      @header dpp/vlarray
+
+      Variable lenght arrays of non POD types are not supported in
+      C++. This class provides a container array which uses storage
+      space passed to constructor. The @ref #DPP_VLARRAY macro can be
+      used to declare storage space buffer along with array container,
+      providing variable lenght array feature:
+
+      @example test/test_vlarray.cc:example
+  */
+  template <typename X>
+  class vlarray
+  {
+  public:
+
+    /** Variable array declaration macro. @This macro declares a
+	buffer array of integers along with a @ref vlarray object and
+	pass the buffer array as storage space to the @ref vlarray
+	constructor. @hidecontent */
+#define DPP_VLARRAY(type, size, name)		\
+  uint64_t _##name[sizeof(type) * size / 8 + 1];	\
+  ::dpp::vlarray<type> name(_##name, size); /* FIXME size alignment */
+
+    typedef X value_type;
+    typedef X & reference;
+    typedef const X & const_reference;
+    typedef X * pointer;
+    typedef const X * const_pointer;
+    typedef unsigned int size_type;
+    typedef int difference_type;
+
+    typedef vlarray_iterator<X, 1> iterator;
+    typedef vlarray_iterator<const X, 1> const_iterator;
+    typedef vlarray_iterator<X, -1> reverse_iterator;
+    typedef vlarray_iterator<const X, -1> const_reverse_iterator;
+
+    /* @This declare a variable lenght array with given storage space
+       and elements count. The default constructor is invoked for all
+       new array items. */
+    vlarray(void *array, size_t size)
+      : _array((X*)array),
+	_size(size)
+    {
+      for (size_t i = 0; i < _size; i++)
+	new ((X*)(_array + i)) X();
+    }
+
+    /* @This invokes destructor for all array items */
+    ~vlarray()
+    {
+      for (size_t i = 0; i < _size; i++)
+	(_array + i)->~X();
+    }
+
+    size_t size() const
+    {
+      return _size;
+    }
+
+    size_t capacity() const
+    {
+      return _size;
+    }
+
+    X & operator[](int i)
+    {
+      return _array[i];
+    }
+
+    const X & operator[](int i) const
+    {
+      return _array[i];
+    }
+
+    X & at(int i)
+    {
+      if (i >= _size)
+	throw std::out_of_range("");
+      return _array[i];
+    }
+
+    const X & at(int i) const
+    {
+      if (i >= _size)
+	throw std::out_of_range("");
+      return _array[i];
+    }
+
+    /** @This returns @ref iterator to first object in pool */
+    iterator begin()
+    {
+      return iterator(_array, 0);
+    }
+
+    /** @This returns end @ref iterator */
+    iterator end()
+    {
+      return iterator(_array, size());
+    }
+
+    /** @This returns @ref const_iterator to first object in pool */
+    const_iterator begin() const
+    {
+      return const_iterator(_array, 0);	
+    }
+
+    /** @This returns end @ref const_iterator */
+    const_iterator end() const
+    {
+      return const_iterator(_array, size());
+    }
+
+    /** @This returns @ref reverse_iterator to last object in pool */
+    reverse_iterator rbegin()
+    {
+      return reverse_iterator(_array, size() - 1);
+    }
+
+    /** @This returns end @ref reverse_iterator */
+    reverse_iterator rend()
+    {
+      return reverse_iterator(_array, -1);
+    }
+
+    /** @This returns @ref const_reverse_iterator to first object in pool */
+    const_reverse_iterator rbegin() const
+    {
+      return const_reverse_iterator(_array, size() - 1);
+    }
+
+    /** @This returns end @ref const_reverse_iterator */
+    const_reverse_iterator rend() const
+    {
+      return const_reverse_iterator(_array, -1);
+    }
+
+  private:
+    X *_array;
+    size_t _size;
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/weak_ptr
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/weak_ptr	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/weak_ptr	(revision 283)
@@ -0,0 +1,170 @@
+/* -*- c++ -*-
+
+   C++ empty pointer classes
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2008-2011 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_EMPTY_REF_HH_
+#define DPP_EMPTY_REF_HH_
+
+/** @file @module{Empty pointer} */
+
+namespace dpp {
+
+  template <class X> class weak_ptr_base;
+  template <class X> class weak_ptr;
+
+  /**
+     @internal
+   */
+  class weak_ptr_node
+  {
+    template <class> friend class weak_ptr_base;
+    template <class> friend class weak_ptr;
+
+    void init()
+    {
+      m_prev = m_next = this;
+    }
+
+    void add(weak_ptr_node *n)
+    {
+      n->m_prev = this;
+      m_next->m_prev = n;
+      n->m_next = m_next;
+      m_next = n;
+    }
+
+    void remove()
+    {
+      m_prev->m_next = m_next;
+      m_next->m_prev = m_prev;
+    }
+
+    weak_ptr_node *m_next;
+    weak_ptr_node *m_prev;
+  };
+
+  /** 
+      @short Empty pointer object base class
+      @module{Empty pointer}
+      @header dpp/weak_ptr
+
+      @This is the referenced object base class, any class which
+      inherits from this class can be pointed to by an @ref weak_ptr
+      pointer.
+   */
+  template <class X>
+  class weak_ptr_base : public weak_ptr_node
+  {
+    template <class> friend class weak_ptr;
+    typedef X _dpp_weak_ptr_type;
+
+  public:
+
+    weak_ptr_base()
+    {
+      weak_ptr_node::init();
+    }
+
+    ~weak_ptr_base()
+    {
+      for (weak_ptr_node *n = weak_ptr_node::m_next;
+	   n != (weak_ptr_node*)this; n = n->m_next)
+	static_cast<weak_ptr<X>*>(n)->_obj = 0;
+    }
+  };
+
+  /** 
+      @short Empty pointer class
+      @module{Empty pointer}
+      @header dpp/weak_ptr
+      @main
+
+      @This implements a pointer class which is automatically set to 0
+      when the associated object is deleted.
+
+      All pointers to the same object are linked together and
+      this list is used to clear all pointers from object
+      destructor. Object class must inherit from the @ref
+      weak_ptr_base class.
+
+      @example test/test_weak_ptr.cc:1
+  */
+  template <class X>
+  class weak_ptr : public weak_ptr_node
+  {
+    template <class> friend class weak_ptr_base;
+
+  public:
+    weak_ptr()
+      : _obj(0)
+    {
+    }
+
+    weak_ptr(X *o)
+      : _obj(o)
+    {
+      const_cast<typename X::_dpp_weak_ptr_type*>(_obj)->add(this);
+    }
+
+    ~weak_ptr()
+    {
+      if (_obj)
+	weak_ptr_node::remove();
+    }
+
+    weak_ptr & operator=(X *o)
+    {
+      if (_obj)
+	weak_ptr_node::remove();
+      _obj = o;
+      if (_obj)
+	const_cast<typename X::_dpp_weak_ptr_type*>(_obj)->add(this);
+      return *this;
+    }
+
+    X & operator*() const
+    {
+      return *_obj;
+    }
+
+    X * operator->() const
+    {
+      return _obj;
+    }
+
+    operator X* () const
+    {
+      return _obj;
+    }
+
+  private:
+    X *_obj;
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/xml
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/xml	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/dpp/xml	(revision 283)
@@ -0,0 +1,1494 @@
+/* -*- c++ -*-
+
+   C++ xml parser template classes
+
+   This file is part of the dpp library of C++ template classes
+
+   doc: http://diaxen.ssji.net/dpp/index.html
+   repo: https://www.ssji.net/svn/projets/trunk/libdpp
+
+   This program is free software: you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation, either version 3 of
+   the License, or (at your option) any later version.
+
+   This program 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+   (c) 2011 Alexandre Becoulet <alexandre.becoulet@free.fr>
+
+*/
+
+#ifndef DPP_XML_HH_
+#define DPP_XML_HH_
+
+/** @file @module{XML} */
+
+#include <map>
+#include <vector>
+#include <string>
+#include <sstream>
+#include <exception>
+#include <cassert>
+#include <cctype>
+
+namespace dpp {
+
+  template <class String> class xml_scanner_ns;
+  template <class String> class xml_scanner;
+
+  /**
+     @short XML error class
+     @module {XML}
+     @header dpp/xml
+   */
+  class xml_error : public std::exception
+  {
+    std::string _what;
+
+  public:
+
+    const char* what() const throw()
+    {
+      return _what.c_str();
+    }
+
+    xml_error(const char *msg, unsigned int line)
+    {
+      std::ostringstream s;
+      s << "XML:" << msg << " at line " << line;
+      _what = s.str();
+    }
+
+    ~xml_error() throw()
+    {
+    }
+  };
+
+  //////////////////////////////////////////////////////////////////////
+  //	XML scanner
+  //////////////////////////////////////////////////////////////////////
+
+  /** @internal */
+  template <class String>
+  class xml_scanner_base
+  {
+    template <class> friend class xml_scanner_ns;
+    template <class> friend class xml_scanner;
+
+  public:
+    /** @This starts XML document scanning. */
+    void scan() throw(xml_error)
+    {
+      process_root();
+    }
+
+  protected:
+    /** @internal */
+    xml_scanner_base(std::istream &i)
+      : _i(&i),
+	_depth(0),
+	_line(1)
+    {
+    }
+
+    /** @This is called on proper document end */
+    virtual void scan_end_doc()
+    {
+    }
+
+    /** @This is called on document start */
+    virtual void scan_start_doc()
+    {
+    }
+
+    /** @This is called for each XML header attribute found */
+    virtual void scan_header_value(const String &name, const String &value)
+    {
+    }
+
+    /** @This is called when a @tt CDATA section has been scand */
+    virtual void scan_cdata(const String &cdata)
+    {
+    }
+
+    /** @This is called when a comment has been scand */
+    virtual void scan_comment(const String &comment)
+    {
+    }
+
+    /** @This is called when a @tt{<! >} directive has been scand */
+    virtual void scan_directive(const String &dir)
+    {
+    }
+
+    /** @This is called when a @tt{<? ?>} instruction has been scand */
+    virtual void scan_instruction(const String &ins)
+    {
+    }
+
+    /** @This is called with content found before the next start/end tag */
+    virtual void scan_content(const String &content)
+    {
+    }
+
+    /** @This is called to substitute entity reference strings. The default
+	implementation handles predefined entities (@em amp, @em apos,
+	@em lt, @em gt and @em quot). */
+    virtual void scan_get_reference(String &ref)
+    {
+      if (ref == "amp")
+	ref = "&";
+      else if (ref == "apos")
+	ref = "'";
+      else if (ref == "gt")
+	ref = ">";
+      else if (ref == "lt")
+	ref = "<";
+      else if (ref == "quot")
+	ref = "\"";
+      else
+	ref = "";
+    }
+
+    /** @This returns current tags nesting level. */
+    unsigned int depth()
+    {
+      return _depth;
+    }
+
+    /** @This returns current line number. */
+    unsigned int line()
+    {
+      return _line;
+    }
+
+    /** @internal throw */
+    void error(const char *msg)
+    {
+      throw xml_error(msg, _line);
+    }
+
+  private:
+    int getc_eof()
+    {
+      char c;
+
+      _i->get(c);
+
+      if (_i->eof())
+	return -1;
+
+      if (!_i->good())
+	error("io error reading xml stream");
+
+      if (c == '\n')
+	_line++;
+
+      return (unsigned char)c;
+    }
+
+    int getc()
+    {
+      int c = getc_eof();
+
+      if (c < 0)
+	error("unexpected end of xml stream");
+
+      return c;
+    }
+
+    void putc(String &str, int c)
+    {
+      str += c;
+    }
+
+    void putc_data(String &str, int c)
+    {
+      switch (c)
+	{
+	case '&':
+	  switch (c = getc())
+	    {
+	      // character reference
+	    case '#': {
+	      int base = 10;
+	      int r = 0;
+	      while ((c = getc()) != ';')
+		{
+		  switch (c)
+		    {
+		    case 'x':
+		      base = 16;
+		      break;
+		    case '0': case '1': case '2': case '3': case '4':
+		    case '5': case '6': case '7': case '8': case '9':
+		      r = r * base + c - '0';
+		      break;
+		    case 'A': case 'B': case 'C':
+		    case 'D': case 'E': case 'F':
+		      r = r * base + 10 + c - 'A';
+		      break;
+		    case 'a': case 'b': case 'c':
+		    case 'd': case 'e': case 'f':
+		      r = r * base + 10 + c - 'a';
+		      break;
+		    default:
+		      error("bad escaping");
+		    }
+		}
+	      return putc(str, r);
+	    }
+
+	      // entity reference
+	    default: {
+	      String ref;
+	      do {
+		ref += c;
+		c = getc();
+	      } while (c != ';');
+	      scan_get_reference(ref);
+	      str += ref;
+	      return;
+	    }
+	    }
+
+	default:
+	  return putc(str, c);
+	}
+    }
+
+    void process_attr_value(String &value, int c)
+    {
+      for (; c != '='; c = getc())
+	if (c > 32)
+	  error("unexpected char in attribute name");
+      for (c = getc(); c != '"' && c != '\''; c = getc())
+	if (c > 32)
+	  error("unexpected char in attribute value");
+      int q = c;
+      for (c = getc(); c != q; c = getc())
+	putc_data(value, c);
+    }
+
+    void process_instruction()
+    {
+      _misc.clear();
+      while (1)
+	{
+	  int c = getc();
+
+	  switch (c)
+	    {
+	    case '?':
+	      if (getc() != '>')
+		error("unexpected char in instruction");
+	      return scan_instruction(_misc);
+
+	    case '"':
+	    case '\'': {
+	      int q = c;
+	      putc_data(_misc, c);
+	      for (c = getc(); c != q; c = getc())
+		putc_data(_misc, c);
+	    }
+
+	    default:
+	      putc(_misc, c);
+	    }
+	}
+    }
+
+    void process_comment()
+    {
+      int c1 = 0, c2 = 0;
+      while (1)
+	{
+	  int c = getc();
+
+	  switch (c)
+	    {
+	    case '>':
+	      if (c1 == '-' && c2 == '-')
+		{
+		  _misc.resize(_misc.size()-2);
+		  return scan_comment(_misc);
+		}
+
+	    default:
+	      c2 = c1;
+	      c1 = c;
+	      putc(_misc, c);
+	    }
+	}
+    }
+
+    void process_cdata()
+    {
+      int c1 = 0, c2 = 0;
+      while (1)
+	{
+	  int c = getc();
+
+	  switch (c)
+	    {
+	    case '>':
+	      if (c1 == ']' && c2 == ']')
+		{
+		  _misc.resize(_misc.size()-2);
+		  return scan_cdata(_misc);
+		}
+
+	    default:
+	      c2 = c1;
+	      c1 = c;
+	      putc(_misc, c);
+	    }
+	}
+    }
+
+    void process_directive()
+    {
+      _misc.clear();
+      while (1)
+	{
+	  int c = getc();
+
+	  switch (c)
+	    {
+	    case '[':
+	      for (const char *s = "CDATA["; *s; s++)
+		if (getc() != *s)
+		  error("bad directive");
+	      return process_cdata();
+
+	    case '-':
+	      if (getc() != '-')
+		error("bad directive");
+	      return process_comment();
+
+	    default: {
+	      int r = 0;
+	      if (_depth)
+		error("unexpected directive inside tag");
+	      do {
+		putc(_misc, c);
+		switch (c)
+		  {
+		  case '"':
+		  case '\'': {
+		    int q = c;
+		    for (c = getc(); c != q; c = getc())
+		      putc_data(_misc, c);
+		    putc_data(_misc, c);
+		    break;
+		  }
+		  case '[':
+		    r++;
+		    break;
+		  case ']':
+		    r--;
+		    break;
+		  }
+		c = getc();
+	      } while (r || c != '>');
+
+	      return scan_directive(_misc);
+	    }
+	    }
+	}
+    }
+
+    virtual void process_assignment(int c) = 0;
+
+    bool process_attributes()
+    {
+      while (1)
+	{
+	  int c = getc();
+
+	  switch (c)
+	    {
+	    case '>':
+	      return false;
+
+	    case '/':	
+	      c = getc();
+	      if (c != '>')
+		error("unexpected char in empty tag");
+	      return true;
+
+	    case ' ':
+	    case '\t':
+	    case '\r':
+	    case '\n':
+	      continue;
+
+	    default:
+	      process_assignment(c);
+	    }
+	}
+    }
+
+    virtual void process_start_tag_name(int c) = 0;
+    virtual void process_end_tag_name() = 0;
+
+    void process_end_tag_tail(int c)
+    {
+      while (c != '>')
+	{
+	  if (c > 32)
+	    error("unexpected char in end tag");
+	  c = getc();
+	}
+    }
+
+    void process_tag()
+    {
+      while (1)
+	{
+	  int c = getc();
+
+	  switch (c)
+	    {
+	    case '?':
+	      return process_instruction();
+	    case '!':
+	      return process_directive();
+
+	    case '/': {
+
+	      if (!_depth--)
+		error("unexpected end tag");
+
+	      process_end_tag_name();
+	      return;
+	    }
+
+	    case ' ':
+	    case '\t':
+	    case '\r':
+	    case '\n':
+	      continue;
+
+	    default:
+	      return process_start_tag_name(c);
+	    }
+	}
+    }
+
+    void process_root()
+    {
+      int c;
+
+      scan_start_doc();
+
+      do {
+	c = getc();
+      } while (c < 32);
+      for (const char *s = "<?xml"; *s; c = getc())
+	if (c > 32 && std::tolower(c) != *s++)
+	  error("bad header");
+      while (1)
+	{
+	  c = getc();
+	  switch (c)
+	    {
+	    case '?':
+	      goto hdr_done;
+
+	    case ' ':
+	    case '\t':
+	    case '\r':
+	    case '\n':
+	      break;
+
+	    default: {
+	      String attr, value;
+
+	      do {
+		putc(attr, c);
+		c = getc();
+	      } while (c > 32 && c != '=');
+
+	      process_attr_value(value, c);
+	      scan_header_value(attr, value);
+	    }
+	    }
+	}
+     hdr_done:
+      if (getc() != '>')
+	error("bad header end");
+
+      c = getc_eof();
+      while (1)
+	{
+	  switch (c)
+	    {
+	    case '<':
+	      process_tag();
+	      break;
+
+	    case -1:
+	      if (_depth)
+		error("unexpected end of xml stream");
+	      scan_end_doc();
+	      return;
+
+	    default: {
+	      String content;
+	      do {
+		putc_data(content, c);
+		c = getc_eof();
+	      } while (c > 0 && c != '<');
+	      scan_content(content);
+	      continue;
+	    }
+	    }
+	  c = getc_eof();
+	}
+    }
+
+  private:
+    std::istream *_i;
+    unsigned int _depth;
+    unsigned int _line;
+    String _misc;
+  };
+
+  /**
+     @short XML scanner
+     @module {XML}
+     @header dpp/xml
+     @see xml_event_parser
+
+     @This implements an XML scanner. Derived classes must override
+     some functions to handle XML scanning events.
+
+     @ref xml_error exception is thrown on syntax error. Start and
+     end tags count must be balanced but tags name missmatch is not checked
+     here.
+
+     The @tt String template parameter may be used to specify a
+     string class with optional wide characters support.
+
+     @section {Example}
+     @example test/test_xml_scanner.cc:scanner P
+     @example test/test_xml_scanner.cc:use
+     @end section
+   */
+  template <class String>
+  class xml_scanner : public xml_scanner_base<String>
+  {
+    typedef xml_scanner_base<String> base;
+    std::istringstream _ss;
+
+  public:
+    /** @This create an xml scanner for processing from input stream. */
+    xml_scanner(std::istream &i)
+      : xml_scanner_base<String>(i)
+    {
+    }
+
+    /** @This create an xml scanner for processing from string content. */
+    xml_scanner(const std::string &s)
+      : _ss(s),
+	xml_scanner_base<String>(_ss)
+    {
+    }
+
+  private:
+
+    void process_assignment(int c)
+    {
+      String attr, value;
+
+      do {
+	base::putc(attr, c);
+	c = base::getc();
+      } while (c > 32 && c != '=');
+
+      base::process_attr_value(value, c);
+      scan_attribute(attr, value);
+    }
+
+    void process_start_tag_name(int c)
+    {
+      String stag;
+      do {
+	base::putc(stag, c);
+	c = base::getc();
+      } while (c > 32 && c != '>' && c != '/');
+
+      if (c == '\n')
+	base::_line--;
+      base::_i->unget();
+
+      scan_start_tag(stag);
+      if (base::process_attributes())
+	scan_end_tag(stag);
+      else
+	base::_depth++;
+    }
+
+    void process_end_tag_name()
+    {
+      String etag;
+      int c;
+
+      while ((c = base::getc()) != '>' && c > 32)
+	base::putc(etag, c);
+
+      base::process_end_tag_tail(c);
+      scan_end_tag(etag);
+    }
+
+  protected:
+
+    /** @This is called for each start tag */
+    virtual void scan_start_tag(const String &start_tag)
+    {
+    }
+
+    /** @This is called for each end tag */
+    virtual void scan_end_tag(const String &end_tag)
+    {
+    }
+
+    /** @This is called for each attribute found in the preceding start tag */
+    virtual void scan_attribute(const String &name, const String &value)
+    {
+    }
+  };
+
+  /**
+     @short XML scanner with namespace support
+     @module {XML}
+     @header dpp/xml
+     @see xml_scanner
+
+     This class implements an XML scanner. This class is similar to
+     @xref{xml_scanner} but tag and attribute namespace name is
+     extracted.
+   */
+  template <class String>
+  class xml_scanner_ns : public xml_scanner_base<String>
+  {
+    typedef xml_scanner_base<String> base;
+
+    std::istringstream _ss;
+
+  public:
+
+    /** @This create an xml scanner for processing from input stream. */
+    xml_scanner_ns(std::istream &i)
+      : xml_scanner_base<String>(i)
+    {
+    }
+
+    /** @This create an xml scanner for processing from string content. */
+    xml_scanner_ns(const std::string &s)
+      : _ss(s),
+	xml_scanner_base<String>(_ss)
+    {
+    }
+
+  private:
+    void process_assignment(int c)
+    {
+      String xmlns, attr, value;
+
+      do {
+	base::putc(xmlns, c);
+	c = base::getc();
+      } while (c > 32 && c != '=' && c != ':');
+
+      if (c == ':') {
+	c = base::getc();
+	do {
+	  base::putc(attr, c);
+	  c = base::getc();
+	} while (c > 32 && c != '=');
+      }
+      else
+	attr.swap(xmlns);
+
+      base::process_attr_value(value, c);
+      scan_attribute(xmlns, attr, value);
+    }
+
+    void process_start_tag_name(int c)
+    {
+      String xmlns;
+      String stag;
+      do {
+	base::putc(xmlns, c);
+	c = base::getc();
+      } while (c > 32 && c != '>' && c != '/' && c != ':');
+
+      if (c == ':') {
+	c = base::getc();
+	do {
+	  base::putc(stag, c);
+	  c = base::getc();
+	} while (c > 32 && c != '>' && c != '/');
+      }
+      else
+	stag.swap(xmlns);
+
+      if (c == '\n')
+	base::_line--;
+      base::_i->unget();
+
+      scan_start_tag(xmlns, stag);
+      if (base::process_attributes())
+	scan_end_tag(xmlns, stag);
+      else
+	base::_depth++;
+    }
+
+    void process_end_tag_name()
+    {
+      String xmlns;
+      String etag;
+      int c;
+
+      while (1)
+	{
+	  c = base::getc();
+	  if (!((c != '>' && c != ':' && c > 32)))
+	    break;
+	  base::putc(xmlns, c);
+	}
+
+      if (c == ':') {
+	while (1)
+	  {
+	    c = base::getc();
+	    if (!((c != '>' && c > 32)))
+	      break;
+	    base::putc(etag, c);
+	  }
+      }
+      else
+	etag.swap(xmlns);
+
+      base::process_end_tag_tail(c);
+      scan_end_tag(xmlns, etag);
+    }
+
+  protected:
+
+    /** @This is called for each start tag */
+    virtual void scan_start_tag(const String &xmlns, const String &start_tag)
+    {
+    }
+
+    /** @This is called for each end tag */
+    virtual void scan_end_tag(const String &xmlns, const String &end_tag)
+    {
+    }
+
+    /** @This is called for each attribute found in the preceding start tag */
+    virtual void scan_attribute(const String &xmlns, const String &name, const String &value)
+    {
+    }
+  };
+
+  /** @internal */
+  struct empty
+  {
+  };
+
+  //////////////////////////////////////////////////////////////////////
+  //	XML event
+  //////////////////////////////////////////////////////////////////////
+
+  template <class String>
+  class xml_event_elements
+  {
+  protected:
+    typedef std::map<String, String> attributes_map_t;
+
+    /** @This is called for each parsed start tag.
+
+	Attributes list is passed as a non-const reference so that it
+	can be swapped with an other empty @ref std::map to avoid data copy.
+
+	@This is called once the new tag @tt Node object has
+	been pushed onto the processing stack, it can be accessed from
+	@this as well as other parsing functions by using the @ref
+	stack_top function.
+
+	@see parse_start_doc @see parse_end_tag
+     */
+    virtual void parse_start_tag(const String &name, attributes_map_t &attributes)
+    {
+    }
+
+    /** @This is called for each parsed end tag.
+
+	@This is called before the ended tag @tt Node object
+	is poped from the processing stack.
+
+	@see parse_start_tag
+    */
+    virtual void parse_end_tag(const String &name)
+    {
+    }
+
+    /** @This is called with content found before the next start/end tag */
+    virtual void parse_content(const String &content)
+    {
+    }
+
+    /** @This is called when a @tt CDATA section has been parsed */
+    virtual void parse_cdata(const String &cdata)
+    {
+    }
+  };
+
+  /**
+     @short XML event parser
+     @module {XML}
+     @header dpp/xml
+     @main
+     @see xml_scanner
+
+     @This implements an XML event based parser. A user @tt Node
+     type may be embedded in the internal processing stack to ease
+     building of in memory tree representation of XML documents (see @xref{example 2}).
+
+     The @tt String template parameter may be used to specify a
+     string class with optional wide characters support.
+
+     @ref xml_error exception is thrown on input error.
+
+     @section {Example 1}
+
+     In this example we simply reprint the XML document during parsing.
+
+     @example test/test_xml_event_parser.cc:parser P
+     @example test/test_xml_event_parser.cc:use
+     @end section
+
+     @section {Example 2}
+
+     In this example we use a @ref ref smart pointer to our @tt MyNode
+     structure to build a tree from XML input. The smart pointer
+     ensures that our tree is automatically freed even if an exception
+     is thrown during parsing.
+
+     @example test/test_xml_event_parser_tree.cc:node P
+     @example test/test_xml_event_parser_tree.cc:parser
+     @example test/test_xml_event_parser_tree.cc:use
+     @end section
+   */
+  template <class String, class Node = empty>
+  class xml_event_parser
+    : protected xml_scanner<String>
+    , public xml_event_elements<String>
+  {
+    typedef xml_scanner<String> base;
+  public:
+    typedef std::map<String, String> attributes_map_t;
+
+    /** @This forwards argument to @ref xml_scanner constructor */
+    template <typename T>
+    xml_event_parser(T &t)
+      : base(t)
+    {
+    }
+
+    /** @This starts XML parsing and returns document root @tt Node. */
+    Node parse() throw(xml_error)
+    {
+      try {
+	xml_scanner<String>::scan();
+      } catch (...) {
+	parse_error();
+	cleanup();
+	throw;
+      }
+
+      Node r = _stack.back()._tc;
+      cleanup();
+      return r;
+    }
+
+  protected:
+
+    using base::line;
+    using base::depth;
+
+    /** @This is called on XML document start.
+
+	XML header attributes list is passed as a non-const reference
+	so that it can be swaped with an other empty @ref std::map to
+	avoid data copy.
+
+	@This is called once the new tag @tt Node object has
+	been pushed onto the processing stack, it can be accessed by using
+	the @ref stack_top function.
+
+	@see parse_start_tag @see parse_end_doc
+     */
+    virtual void parse_start_doc(attributes_map_t &header_values)
+    {
+    }
+
+    /** @This is called on XML document parse end */
+    virtual void parse_end_doc()
+    {
+    }
+
+    /** @This is called when a "@tt{<! >}" directive has been parsed */
+    virtual void parse_directive(const String &dir)
+    {
+    }
+
+    /** @This is called when a comment has been parsed */
+    virtual void parse_comment(const String &comment)
+    {
+    }
+
+    /** @This is called when a "@tt{<? ?>}" instruction has been parsed */
+    virtual void parse_instruction(const String &ins)
+    {
+    }
+
+    /** @This is called when a parse error occurs, before the internal
+	stack is destroyed */
+    virtual void parse_error()
+    {
+    }
+
+    /** @This returns node on stack relative to stack top, -1 is stack top. */
+    Node & stack_top(int i)
+    {
+      return _stack[_stack.size() + i]._tc;
+    }
+
+    /** @This returns node on stack relative to stack bottom, 0 is stack bottom. */
+    Node & stack_bottom(int i)
+    {
+      return _stack[i]._tc;
+    }
+
+    /** @This returns current stack size */
+    size_t stack_size()
+    {
+      return _stack.size();
+    }
+
+  private:
+
+    /** @override */
+    void scan_cdata(const String &cdata)
+    {
+      (this->*_do_start)();
+      parse_cdata(cdata);
+    }
+
+    /** @override */
+    void scan_comment(const String &comment)
+    {
+      (this->*_do_start)();
+      parse_comment(comment);
+    }
+
+    /** @override */
+    void scan_directive(const String &dir)
+    {
+      (this->*_do_start)();
+      parse_directive(dir);
+    }
+
+    /** @override */
+    void scan_instruction(const String &ins)
+    {
+      (this->*_do_start)();
+      parse_instruction(ins);
+    }
+
+    /** @override */
+    void scan_content(const String &content)
+    {
+      (this->*_do_start)();
+      parse_content(content);
+    }
+
+    /** @override */
+    void scan_attribute(const String &name, const String &value)
+    {
+      _attr[name] = value;
+    }
+
+    /** @override */
+    void scan_start_tag(const String &start_tag)
+    {
+      (this->*_do_start)();
+      _attr.clear();
+      _started_tag = start_tag;
+      _do_start = &xml_event_parser::do_start_tag;
+    }
+
+    /** @override */
+    void scan_end_tag(const String &end_tag)
+    {
+      (this->*_do_start)();
+      assert(_stack.size() > 1);
+      if (_stack.back()._name != end_tag)
+	base::error("end tag name doesn't match");
+      parse_end_tag(_stack.back()._name);
+      _stack.pop_back();
+    }
+
+    /** @override */
+    void scan_start_doc()
+    {
+      _do_start = &xml_event_parser::do_start_doc;
+    }
+
+    /** @override */
+    void scan_header_value(const String &name, const String &value)
+    {
+      _attr[name] = value;
+    }
+
+    /** @override */
+    void scan_end_doc()
+    {
+      assert(_stack.size() == 1);
+      parse_end_doc();
+    }
+
+    void do_start_none()
+    {
+    }
+
+    void do_start_doc()
+    {
+      _do_start = &xml_event_parser::do_start_none;
+      _stack.push_back(stack_item(""));
+      parse_start_doc(_attr);
+    }
+
+    void do_start_tag()
+    {
+      _do_start = &xml_event_parser::do_start_none;
+      _stack.push_back(stack_item(_started_tag));
+      parse_start_tag(_started_tag, _attr);
+    }
+
+    void cleanup()
+    {
+      _stack.clear();
+      _attr.clear();
+      _started_tag.clear();
+    }
+
+    struct stack_item
+    {
+      stack_item(const String &name)
+	: _name(name), _tc()
+      {
+      }
+
+      String _name;
+      Node _tc;
+    };
+
+    std::vector<stack_item>  _stack;
+    std::map<String, String> _attr;
+    void (xml_event_parser::*_do_start)();
+    String _started_tag;
+  };
+
+  /**
+     @short XML event parser with namespace support
+     @module {XML}
+     @header dpp/xml
+     @main
+     @see xml_event_parser
+
+     This class implements an XML event based parser.
+   */
+
+  //////////////////////////////////////////////////////////////////////
+  //	XML dom
+  //////////////////////////////////////////////////////////////////////
+
+  class xml_dom_node;
+  inline std::ostream & operator<<(std::ostream &o, const xml_dom_node &node);
+
+  /**
+     @short XML dom node base class
+     @module {XML}
+     @header dpp/xml
+  */
+  class xml_dom_node
+  {
+    friend std::ostream & operator<<(std::ostream &o, const xml_dom_node &node);
+    template <class> friend class xml_dom_parser;
+    template <class> friend class xml_dom_parent_node;
+    template <class> friend class xml_dom_element;
+
+  protected:
+    virtual ~xml_dom_node()
+    {
+    }
+
+    void push_back(xml_dom_node *b)
+    {
+      xml_dom_node *a = this;
+      b->_prev = a;
+      a->_next->_prev = b;
+      b->_next = a->_next;
+      a->_next = b;
+    }
+
+    void push_front(xml_dom_node *b)
+    {
+      xml_dom_node *a = this;
+      b->_next = a;
+      a->_prev->_next = b;
+      b->_prev = a->_prev;
+      a->_prev = b;
+    }
+
+    bool empty() const
+    {
+      return _next == _prev;
+    }
+
+  private:
+    virtual void print(std::ostream &o) const
+    {
+    }
+
+    xml_dom_node *_next;
+    xml_dom_node *_prev;
+  };
+
+  inline std::ostream & operator<<(std::ostream &o, const xml_dom_node &node)
+  {
+    node.print(o);
+    return o;
+  }
+
+  /** @internal */
+  template <class String>
+  class xml_dom_parent_node : public xml_dom_node
+  {
+    template <class> friend class xml_dom_parser;
+
+  protected:
+    typedef xml_dom_node chld_base;
+    typedef xml_dom_node root_base;
+    typedef std::map<String, xml_dom_node *> child_hash_t;
+
+    xml_dom_parent_node()
+    {
+      _root._next = &_root;
+      _root._prev = &_root;
+    }
+
+    ~xml_dom_parent_node()
+    {
+      cleanup();
+    }
+
+    void print(std::ostream &o) const
+    {
+      for (xml_dom_node *i = _root._next; i != &_root; i = i->_next)
+	i->print(o);
+    }
+
+    void cleanup()
+    {
+      xml_dom_node *j;
+      for (xml_dom_node *i = _root._next; i != &_root; i = j)
+	{
+	  j = i->_next;
+	  delete i;
+	}
+    }
+
+    xml_dom_node _root;
+    child_hash_t _children;
+  };
+
+  /** @internal */
+  template <class String>
+  class xml_dom_attr_node
+  {
+    typedef std::map<String, String> attr_hash_t;
+
+  public:
+    /** @This returns a reference to attributes map */
+    const attr_hash_t &get_attributes() const
+    {
+      return _attrs;
+    }
+
+    /** @This returns a modifiable reference to attributes map */
+    attr_hash_t &get_attributes()
+    {
+      return _attrs;
+    }
+
+    /** @This returns value of the specified attribute or default a value */
+    const String &get_attribute(const String &name, const String &default_ = String())
+    {
+      typename attr_hash_t::const_iterator i = _attrs.find(name);
+
+      if (i == _attrs.end())
+	return default_;
+
+      return i->second;
+    }
+
+  protected:
+
+    void print_attr(std::ostream &o) const
+    {
+      for (typename attr_hash_t::const_iterator i = _attrs.begin();
+	   i != _attrs.end(); i++)
+	o << " " << i->first << "=\"" << i->second << "\"";
+    }
+
+    attr_hash_t _attrs;
+  };
+
+  /**
+     @short XML dom document root node
+     @module {XML}
+     @header dpp/xml
+  */
+  template <class String>
+  class xml_dom_doc
+    : public xml_dom_parent_node<String>
+    , public xml_dom_attr_node<String>
+  {
+    template <class> friend class xml_dom_parser;
+    typedef xml_dom_parent_node<String> base;
+
+    void print(std::ostream &o) const
+    {
+      o << "<?xml";
+      xml_dom_attr_node<String>::print_attr(o);
+      o << " ?>";
+      base::print(o);
+    }
+  };
+
+  /**
+     @short XML dom tag element
+     @module {XML}
+     @header dpp/xml
+  */
+  template <class String>
+  class xml_dom_element
+    : public xml_dom_parent_node<String>
+    , public xml_dom_attr_node<String>
+  {
+    template <class> friend class xml_dom_parser;
+    typedef xml_dom_parent_node<String> base;
+
+  public:
+    typedef std::map<String, String> attr_hash_t;
+
+    /** @This returns element name  */
+    const String &get_name() const
+    {
+    }
+
+    /** @This changes element name  */
+    void set_name(const String &name) const
+    {
+      _name = name;
+    }
+
+  private:
+    xml_dom_element(const String &name)
+      : _name(name)
+    {
+    }
+
+    void print(std::ostream &o) const
+    {
+      o << "<" << _name;
+      xml_dom_attr_node<String>::print_attr(o);
+      if (base::_root.empty())
+	o << " />";
+      else
+	{
+	  o << ">";
+	  base::print(o);
+	  o << "</" << _name << ">";
+	}
+    }
+
+    String _name;
+  };
+
+  /**
+     @short XML dom text and CDATA content node
+     @module {XML}
+     @header dpp/xml
+  */
+  template <class String>
+  class xml_dom_content : public xml_dom_node
+  {
+    template <class> friend class xml_dom_parser;
+
+  public:
+    /** @this returns content */
+    const String & get_content() const
+    {
+      return _content;
+    }
+
+    /** @this changes content */
+    void set_content(const String &content) const
+    {
+      _content = content;
+    }
+
+    /** @this returns true if content is in a CDATA section in xml file */
+    const bool is_cdata() const
+    {
+      return _is_cdata;
+    }
+
+  private:
+    xml_dom_content(const String &content, bool is_cdata = false)
+      : _content(content),
+	_is_cdata(is_cdata)
+    {
+    }
+
+    void print(std::ostream &o) const
+    {
+      if (_is_cdata)
+	o << "<![CDATA[" << _content << "]]>";
+      else
+	o << _content;
+    }
+
+    String _content;
+    bool _is_cdata;
+  };
+
+  /**
+     @short XML dom parser
+     @module {XML}
+     @header dpp/xml
+     @see xml_event_parser
+     @main
+
+     @This implements an XML dom parser. It builds an in memory
+     tree representation of the XML input.
+
+     The @ref parse function must be used to start XML input parsing.
+     Nodes can be used with @ref std::ostream objects to write XML
+     output.
+
+     The @tt String template parameter may be used to specify a
+     string class with optional wide characters support.
+
+     @ref xml_error exception is thrown on input error.
+
+     @section {Example}
+     @example test/test_xml_dom_parser.cc:read P
+     @end section
+  */
+  template <class String>
+  class xml_dom_parser : protected xml_event_parser<String, xml_dom_parent_node<String>*>
+  {
+    typedef xml_event_parser<String, xml_dom_parent_node<String>*> base;
+    typedef xml_dom_element<String> element_t;
+    typedef xml_dom_node node_t;
+
+  public:
+    typedef std::map<String, String> attributes_map_t;
+
+    /** @This forwards argument to @ref xml_event_parser constructor */
+    template <typename T>
+    xml_dom_parser(T &t)
+      : base(t)
+    {
+    }
+
+    /** @This parses input and returns the root node */
+    xml_dom_doc<String> * parse() throw(xml_error)
+    {
+      xml_dom_doc<String> *r;
+
+      try {
+	r = static_cast<xml_dom_doc<String>*>(base::parse());
+      } catch (...) {
+	throw;
+      }
+
+      return r;
+    }
+
+  private:
+
+    /** @override */
+    void parse_start_doc(attributes_map_t &attrs)
+    {
+      xml_dom_doc<String> *r = new xml_dom_doc<String>();
+      base::stack_top(-1) = r;
+      r->_attrs.swap(attrs);
+    }
+
+    /** @override */
+    void parse_start_tag(const String &name, attributes_map_t &attrs)
+    {
+      element_t *e = new xml_dom_element<String>(name);
+      base::stack_top(-1) = e;
+      e->_attrs.swap(attrs);
+    }
+
+    /** @override */
+    void parse_end_tag(const String &name)
+    {
+      base::stack_top(-2)->_root.push_front(base::stack_top(-1));
+    }
+
+    /** @override */
+    void parse_content(const String &content)
+    {
+      xml_dom_content<String> *c = new xml_dom_content<String>(content, false);
+      base::stack_top(-1)->_root.push_front(c);
+    }
+
+    /** @override */
+    void parse_cdata(const String &content)
+    {
+      xml_dom_content<String> *c = new xml_dom_content<String>(content, true);
+      base::stack_top(-1)->_root.push_front(c);
+    }
+
+    /** @override */
+    void parse_error()
+    {
+      for (size_t i = 0; i < base::stack_size(); i++)
+	delete base::stack_bottom(i);
+    }
+
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile	(revision 283)
@@ -0,0 +1,455 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# src/elfpp/Makefile.  Generated from Makefile.in by configure.
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+
+
+pkgdatadir = $(datadir)/libelfpp
+pkglibdir = $(libdir)/libelfpp
+pkglibexecdir = $(libexecdir)/libelfpp
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = x86_64-unknown-linux-gnu
+host_triplet = x86_64-unknown-linux-gnu
+subdir = src/elfpp
+DIST_COMMON = $(pkginclude_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.hh
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkgincludedir)"
+HEADERS = $(pkginclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgincludedir = $(includedir)/elfpp
+ACLOCAL = ${SHELL} /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/build/missing --run aclocal-1.11
+AMTAR = ${SHELL} /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/build/missing --run tar
+AR = ar
+AUTOCONF = ${SHELL} /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/build/missing --run autoconf
+AUTOHEADER = ${SHELL} /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/build/missing --run autoheader
+AUTOMAKE = ${SHELL} /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/build/missing --run automake-1.11
+AWK = gawk
+CC = gcc
+CCDEPMODE = depmode=gcc3
+CFLAGS = -g -O2
+CPP = gcc -E
+CPPFLAGS = 
+CXX = g++
+CXXCPP = g++ -E
+CXXDEPMODE = depmode=gcc3
+CXXFLAGS = -g -O2
+CYGPATH_W = echo
+DEFS = -DHAVE_CONFIG_H
+DEPDIR = .deps
+DSYMUTIL = 
+DUMPBIN = 
+ECHO_C = 
+ECHO_N = -n
+ECHO_T = 
+EGREP = /bin/grep -E
+EXEEXT = 
+FGREP = /bin/grep -F
+GREP = /bin/grep
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_SCRIPT = ${INSTALL}
+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
+LD = /usr/bin/ld -m elf_x86_64
+LDFLAGS = 
+LIBOBJS = 
+LIBS = 
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LIPO = 
+LN_S = ln -s
+LTLIBOBJS = 
+MAKEINFO = ${SHELL} /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/build/missing --run makeinfo
+MKDIR_P = /bin/mkdir -p
+NM = /usr/bin/nm -B
+NMEDIT = 
+OBJDUMP = objdump
+OBJEXT = o
+OTOOL = 
+OTOOL64 = 
+PACKAGE = libelfpp
+PACKAGE_BUGREPORT = 
+PACKAGE_NAME = libelfpp
+PACKAGE_STRING = libelfpp 1.0
+PACKAGE_TARNAME = libelfpp
+PACKAGE_VERSION = 1.0
+PATH_SEPARATOR = :
+RANLIB = ranlib
+SED = /bin/sed
+SET_MAKE = 
+SHELL = /bin/sh
+STRIP = strip
+VERSION = 1.0
+abs_builddir = /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/src/elfpp
+abs_srcdir = /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/src/elfpp
+abs_top_builddir = /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp
+abs_top_srcdir = /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp
+ac_ct_CC = gcc
+ac_ct_CXX = g++
+ac_ct_DUMPBIN = 
+am__include = include
+am__leading_dot = .
+am__quote = 
+am__tar = ${AMTAR} chof - "$$tardir"
+am__untar = ${AMTAR} xf -
+bindir = ${exec_prefix}/bin
+build = x86_64-unknown-linux-gnu
+build_alias = 
+build_cpu = x86_64
+build_os = linux-gnu
+build_vendor = unknown
+builddir = .
+datadir = ${datarootdir}
+datarootdir = ${prefix}/share
+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
+dvidir = ${docdir}
+exec_prefix = ${prefix}
+host = x86_64-unknown-linux-gnu
+host_alias = 
+host_cpu = x86_64
+host_os = linux-gnu
+host_vendor = unknown
+htmldir = ${docdir}
+includedir = ${prefix}/include
+infodir = ${datarootdir}/info
+install_sh = ${SHELL} /users/cao/karaoui/soc/myplateform/caba_vgsb_almo_mmu_vloader/soft/mover/libelfpp/build/install-sh
+libdir = ${exec_prefix}/lib
+libexecdir = ${exec_prefix}/libexec
+localedir = ${datarootdir}/locale
+localstatedir = ${prefix}/var
+lt_ECHO = echo
+mandir = ${datarootdir}/man
+mkdir_p = /bin/mkdir -p
+oldincludedir = /usr/include
+pdfdir = ${docdir}
+prefix = /users/cao/karaoui/.local/bin
+program_transform_name = s,x,x,
+psdir = ${docdir}
+sbindir = ${exec_prefix}/sbin
+sharedstatedir = ${prefix}/com
+srcdir = .
+sysconfdir = ${prefix}/etc
+target_alias = 
+top_build_prefix = ../../
+top_builddir = ../..
+top_srcdir = ../..
+pkginclude_HEADERS = access elfpp_access.hh elfpp_access.hxx			\
+	elfpp_bits.hh elfpp.hh elfpp_object.hh elfpp_object.hxx			\
+	elfpp_reloc.hh elfpp_reloc.hxx elfpp_segment.hh				\
+	elfpp_segment.hxx elfpp_section.hh elfpp_section.hxx			\
+	elfpp_symbol.hh elfpp_symbol.hxx object reloc section symbol segment
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/elfpp/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/elfpp/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
+	done
+
+uninstall-pkgincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(pkgincludedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgincludeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pkgincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-libtool ctags distclean distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-pkgincludeHEADERS install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-pkgincludeHEADERS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile.am
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile.am	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile.am	(revision 283)
@@ -0,0 +1,9 @@
+
+pkgincludedir = $(includedir)/elfpp
+
+pkginclude_HEADERS = access elfpp_access.hh elfpp_access.hxx			\
+	elfpp_bits.hh elfpp.hh elfpp_object.hh elfpp_object.hxx			\
+	elfpp_reloc.hh elfpp_reloc.hxx elfpp_segment.hh				\
+	elfpp_segment.hxx elfpp_section.hh elfpp_section.hxx			\
+	elfpp_symbol.hh elfpp_symbol.hxx object reloc section symbol segment
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile.in
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile.in	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/Makefile.in	(revision 283)
@@ -0,0 +1,455 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/elfpp
+DIST_COMMON = $(pkginclude_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.hh
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkgincludedir)"
+HEADERS = $(pkginclude_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgincludedir = $(includedir)/elfpp
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+pkginclude_HEADERS = access elfpp_access.hh elfpp_access.hxx			\
+	elfpp_bits.hh elfpp.hh elfpp_object.hh elfpp_object.hxx			\
+	elfpp_reloc.hh elfpp_reloc.hxx elfpp_segment.hh				\
+	elfpp_segment.hxx elfpp_section.hh elfpp_section.hxx			\
+	elfpp_symbol.hh elfpp_symbol.hxx object reloc section symbol segment
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/elfpp/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/elfpp/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
+	done
+
+uninstall-pkgincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(pkgincludedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgincludeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pkgincludeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-libtool ctags distclean distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-pkgincludeHEADERS install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-pkgincludeHEADERS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/access
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/access	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/access	(revision 283)
@@ -0,0 +1,4 @@
+
+#include "elfpp_access.hh"
+#include "elfpp_access.hxx"
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp.hh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp.hh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp.hh	(revision 283)
@@ -0,0 +1,47 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_HH_
+#define ELFPP_HH_
+
+#include <map>
+
+#include <dpp/linked_list>
+
+namespace elfpp
+{
+  class symbol;
+
+  typedef std::multimap<const std::string, symbol *> sym_tab_map_t;
+
+  class reloc;
+
+  typedef dpp::linked_list<reloc, 0> reloc_table_t;
+  typedef dpp::linked_list<reloc, 1> reloc_modlist_t;
+
+  class section;
+  typedef dpp::linked_list<section> section_table_t;
+
+  class segment;
+  typedef dpp::linked_list<segment> segment_table_t;
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_access.hh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_access.hh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_access.hh	(revision 283)
@@ -0,0 +1,112 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_ACCESS_HH_
+#define ELFPP_ACCESS_HH_
+
+#include <stdio.h>
+#include "elfpp_bits.hh"
+
+namespace elfpp
+{
+
+  class object;
+  class section;
+  class reloc;
+
+  /** @internal */
+  class elf_access
+  {
+  public:
+    virtual ~elf_access() {}
+    virtual void read(object &obj, FILE *file) = 0;
+    virtual void write(object &obj, FILE *file) = 0;
+    virtual void load_symtab(object &obj) = 0;
+    virtual void load_reltab(object &obj) = 0;
+    virtual void save_symtab(object &obj) = 0;
+  };
+
+  /** @internal */
+  template <class bits_t, int width>
+  class elfn_access : public elf_access
+  {
+    typedef typename bits_t::elf_hdr_t elf_hdr_t;
+    typedef typename bits_t::elf_shdr_t elf_shdr_t;
+    typedef typename bits_t::elf_phdr_t elf_phdr_t;
+    typedef typename bits_t::elf_sym_t elf_sym_t;
+    typedef typename bits_t::elf_rel_t elf_rel_t;
+    typedef typename bits_t::elf_rela_t elf_rela_t;
+
+    void load_symtab(object &obj);
+    void load_reltab(object &obj);
+    void save_symtab(object &obj);
+    void create_segments(object &obj);
+
+    void read(object &obj, FILE *file);
+    void write(object &obj, FILE *file);
+
+    inline uint16_t swap(uint16_t x);
+    inline uint32_t swap(uint32_t x);
+    inline uint64_t swap(uint64_t x);
+
+    inline int16_t swap(int16_t x);
+    inline int32_t swap(int32_t x);
+    inline int64_t swap(int64_t x);
+
+    inline unsigned int rel_sym(uint64_t info);
+    inline enum reloc_e rel_type(uint64_t info);
+    inline uint64_t rel_info(unsigned int sym, enum reloc_e type);
+
+    void load_addend(const object &obj, reloc &r, const elf_rel_t *reltab, size_t count, int index, uint8_t *data);
+    void rel_write(const object &obj, enum reloc_e type, void *data, int64_t value);
+
+    template <typename X, typename Y>
+    inline void swap(X *a, Y x);
+
+    ei_data_e byteorder_;
+  };
+
+  struct elf32_bits_s
+  {
+    typedef Elf32_Ehdr elf_hdr_t;
+    typedef Elf32_Shdr elf_shdr_t;
+    typedef Elf32_Phdr elf_phdr_t;
+    typedef Elf32_Sym elf_sym_t;
+    typedef Elf32_Rel elf_rel_t;
+    typedef Elf32_Rela elf_rela_t;
+  };
+
+  struct elf64_bits_s
+  {
+    typedef Elf64_Ehdr elf_hdr_t;
+    typedef Elf64_Shdr elf_shdr_t;
+    typedef Elf64_Phdr elf_phdr_t;
+    typedef Elf64_Sym elf_sym_t;
+    typedef Elf64_Rel elf_rel_t;
+    typedef Elf64_Rela elf_rela_t;
+  };
+
+  typedef elfn_access<elf32_bits_s, 32> elf32_access;
+  typedef elfn_access<elf64_bits_s, 64> elf64_access;
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_access.hxx
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_access.hxx	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_access.hxx	(revision 283)
@@ -0,0 +1,140 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_ACCESS_HXX_
+#define ELFPP_ACCESS_HXX_
+
+#ifdef __linux__
+
+# include <endian.h>
+
+#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+
+# include <machine/endian.h>
+# define __BYTE_ORDER BYTE_ORDER
+# define __LITTLE_ENDIAN LITTLE_ENDIAN
+# define __BIG_ENDIAN BIG_ENDIAN
+
+#else
+# error Unable to guess endianness
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define SWAPVALUE ELFDATA2MSB
+#elif __BYTE_ORDER == __BIG_ENDIAN
+# define SWAPVALUE ELFDATA2LSB
+#endif
+
+namespace elfpp
+{
+ 
+  template <typename bits_t, int width>
+  unsigned int elfn_access<bits_t, width>::rel_sym(uint64_t info)
+  {
+    if (width == 32)
+      return info >> 8;
+    else
+      return info >> 32;
+  }
+
+  template <typename bits_t, int width>
+  enum reloc_e elfn_access<bits_t, width>::rel_type(uint64_t info)
+  {
+    if (width == 32)
+      return (enum reloc_e)(info & 0xff);
+    else
+      return (enum reloc_e)(info & 0xffffffff);
+  }
+
+  template <typename bits_t, int width>
+  uint64_t elfn_access<bits_t, width>::rel_info(unsigned int sym, enum reloc_e type)
+  {
+    if (width == 32)
+      return (sym << 8) | (type & 0xff);
+    else
+      return ((uint64_t)sym << 32) | type;
+  }
+
+  template <typename bits_t, int width>
+  uint16_t elfn_access<bits_t, width>::swap(uint16_t x)
+  {
+    if (byteorder_ == SWAPVALUE)
+      return (x << 8) | (x >> 8);
+
+    return x;
+  }
+
+  template <typename bits_t, int width>
+  int16_t elfn_access<bits_t, width>::swap(int16_t x)
+  {
+    return swap((uint16_t)x);
+  }
+
+  template <typename bits_t, int width>
+  uint32_t elfn_access<bits_t, width>::swap(uint32_t x)
+  {
+    if (byteorder_ == SWAPVALUE)
+      return (((x >> 24) & 0x000000ff) |
+	      ((x >> 8 ) & 0x0000ff00) |
+	      ((x << 8 ) & 0x00ff0000) |
+	      ((x << 24) & 0xff000000));
+
+    return x;
+  }
+
+  template <typename bits_t, int width>
+  int32_t elfn_access<bits_t, width>::swap(int32_t x)
+  {
+    return swap((uint32_t)x);
+  }
+
+  template <typename bits_t, int width>
+  uint64_t elfn_access<bits_t, width>::swap(uint64_t x)
+  {
+    if (byteorder_ == SWAPVALUE)
+      return (((x >> 56) & 0x00000000000000ffLL) |
+	      ((x >> 40) & 0x000000000000ff00LL) |
+	      ((x >> 24) & 0x0000000000ff0000LL) |
+	      ((x >>  8) & 0x00000000ff000000LL) |
+	      ((x <<  8) & 0x000000ff00000000LL) |
+	      ((x << 24) & 0x0000ff0000000000LL) |
+	      ((x << 40) & 0x00ff000000000000LL) |
+	      ((x << 56) & 0xff00000000000000LL));
+
+    return x;
+  }
+
+  template <typename bits_t, int width>
+  int64_t elfn_access<bits_t, width>::swap(int64_t x)
+  {
+    return swap((uint64_t)x);
+  }
+
+  template <typename bits_t, int width>
+  template <typename X, typename Y>
+  void elfn_access<bits_t, width>::swap(X *a, Y x)
+  {
+    *a = swap((X)x);
+  }
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_bits.hh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_bits.hh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_bits.hh	(revision 283)
@@ -0,0 +1,1896 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+    Based on part of the GNU C Library (LGPL).
+    Copyright (C) 1995-2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+*/
+
+#ifndef ELFPP_BITS_H_
+#define	ELFPP_BITS_H_
+
+#include <stdint.h>
+
+/// Provide bit mask operations for an enum type
+#define ELF_ENUM_OPS(type)			\
+						\
+    inline type operator| (type a, type b)	\
+    {						\
+      return (type)((int)a | (int)b);		\
+    }						\
+						\
+    inline type operator& (type a, type b)	\
+    {						\
+      return (type)((int)a & (int)b);		\
+    }						\
+						\
+    inline type operator~ (type a)		\
+    {						\
+      return (type)(~(int)a);			\
+    }
+
+namespace elfpp
+{
+
+/* Standard ELF types.  */
+
+/** @multiple Type for a 16-bit quantity.  */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/** @multiple Type for signed and unsigned 32-bit quantities.  */
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef	int32_t  Elf64_Sword;
+
+/**  @multiple Type for signed and unsigned 64-bit quantities.  */
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef	int64_t  Elf64_Sxword;
+
+/** @multiple Type of addresses.  */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/** @multiple Type of file offsets.  */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/** @multiple Type for section indices, which are 16-bit quantities.  */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/** @multiple Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/** @multiple The ELF file header.  This appears at the start of every ELF file.  */
+
+  static const unsigned int EI_NIDENT = 16;
+
+  struct Elf32_Ehdr
+  {
+    unsigned char	e_ident[EI_NIDENT];	//< Magic number and other info 
+    Elf32_Half	e_type;		//< Object file type 
+    Elf32_Half	e_machine;	//< Architecture 
+    Elf32_Word	e_version;	//< Object file version 
+    Elf32_Addr	e_entry;	//< Entry point virtual address 
+    Elf32_Off	e_phoff;	//< Program header table file offset 
+    Elf32_Off	e_shoff;	//< Section header table file offset 
+    Elf32_Word	e_flags;	//< Processor-specific flags 
+    Elf32_Half	e_ehsize;	//< ELF header size in bytes 
+    Elf32_Half	e_phentsize;	//< Program header table entry size 
+    Elf32_Half	e_phnum;	//< Program header table entry count 
+    Elf32_Half	e_shentsize;	//< Section header table entry size 
+    Elf32_Half	e_shnum;	//< Section header table entry count 
+    Elf32_Half	e_shstrndx;	//< Section header string table index 
+  };
+
+  struct Elf64_Ehdr
+  {
+    unsigned char	e_ident[EI_NIDENT];	//< Magic number and other info 
+    Elf64_Half	e_type;		//< Object file type 
+    Elf64_Half	e_machine;	//< Architecture 
+    Elf64_Word	e_version;	//< Object file version 
+    Elf64_Addr	e_entry;	//< Entry point virtual address 
+    Elf64_Off	e_phoff;	//< Program header table file offset 
+    Elf64_Off	e_shoff;	//< Section header table file offset 
+    Elf64_Word	e_flags;	//< Processor-specific flags 
+    Elf64_Half	e_ehsize;	//< ELF header size in bytes 
+    Elf64_Half	e_phentsize;	//< Program header table entry size 
+    Elf64_Half	e_phnum;	//< Program header table entry count 
+    Elf64_Half	e_shentsize;	//< Section header table entry size 
+    Elf64_Half	e_shnum;	//< Section header table entry count 
+    Elf64_Half	e_shstrndx;	//< Section header string table index 
+  };
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+/** @multiple Conglomeration of the identification bytes, for easy testing as a word.  */
+#define	ELFMAG		"\177ELF"
+
+  static const unsigned int EI_CLASS = 4;	//< File class byte index
+
+  enum ei_class_e
+    {
+      ELFCLASSNONE = 0,		//< Invalid class 
+      ELFCLASS32 = 1,		//< 32-bit objects 
+      ELFCLASS64 = 2,		//< 64-bit objects 
+      ELFCLASSNUM = 3,
+    };
+
+  static const unsigned int EI_DATA = 5;	//< Data encoding byte index
+
+  enum ei_data_e
+    {
+      ELFDATANONE = 0,	//< Invalid data encoding 
+      ELFDATA2LSB = 1,	//< 2's complement, little endian 
+      ELFDATA2MSB = 2,	//< 2's complement, big endian 
+      ELFDATANUM = 3,
+    };
+
+  static const unsigned int EI_VERSION = 6;	//< File version byte index Value must be EV_CURRENT 
+
+  static const unsigned int EI_OSABI = 7;	//< OS ABI identification 
+
+  enum ei_osabi_e
+    {
+      ELFOSABI_NONE = 0,	//< UNIX System V ABI 
+      ELFOSABI_SYSV = 0,	//< Alias.  
+      ELFOSABI_HPUX = 1,	//< HP-UX 
+      ELFOSABI_NETBSD = 2,	//< NetBSD.  
+      ELFOSABI_LINUX = 3,	//< Linux.  
+      ELFOSABI_SOLARIS = 6,	//< Sun Solaris.  
+      ELFOSABI_AIX = 7,		//< IBM AIX.  
+      ELFOSABI_IRIX = 8,	//< SGI Irix.  
+      ELFOSABI_FREEBSD = 9,	//< FreeBSD.  
+      ELFOSABI_TRU64 = 10,	//< Compaq TRU64 UNIX.  
+      ELFOSABI_MODESTO = 11,	//< Novell Modesto.  
+      ELFOSABI_OPENBSD = 12,	//< OpenBSD.  
+      ELFOSABI_ARM = 97,	//< ARM 
+      ELFOSABI_STANDALONE = 255,	//< Standalone (embedded) application 
+    };
+
+  static const unsigned int EI_ABIVERSION	= 8;	//< ABI version 
+
+  static const unsigned int EI_PAD = 9;	//< Byte index of padding bytes 
+
+/** Legal values for e_type (object file type).  */
+
+  enum e_type_e
+    {
+      ET_NONE = 0,	//< No file type 
+      ET_REL = 1,	//< Relocatable file 
+      ET_EXEC = 2,	//< Executable file 
+      ET_DYN = 3,	//< Shared object file 
+      ET_CORE = 4,	//< Core file 
+      ET_NUM = 5,	//< Number of defined types 
+      ET_LOOS = 0xfe00,	//< OS-specific range start 
+      ET_HIOS = 0xfeff,	//< OS-specific range end 
+      ET_LOPROC = 0xff00,	//< Processor-specific range start 
+      ET_HIPROC = 0xffff,	//< Processor-specific range end 
+    };
+
+/** Legal values for e_machine (architecture).  */
+
+  enum e_machine_e
+    {
+      EM_NONE = 0,	//< No machine 
+      EM_M32 = 1,	//< AT&T WE 32100 
+      EM_SPARC = 2,	//< SUN SPARC 
+      EM_386 = 3,	//< Intel 80386 
+      EM_68K = 4,	//< Motorola m68k family 
+      EM_88K = 5,	//< Motorola m88k family 
+      EM_860 = 7,	//< Intel 80860 
+      EM_MIPS = 8,	//< MIPS R3000 big-endian 
+      EM_S370 = 9,	//< IBM System/370 
+      EM_MIPS_RS3_LE = 10,	//< MIPS R3000 little-endian 
+      EM_PARISC = 15,	//< HPPA 
+      EM_VPP500 = 17,	//< Fujitsu VPP500 
+      EM_SPARC32PLUS = 18,	//< Sun's "v8plus" 
+      EM_960 = 19,	//< Intel 80960 
+      EM_PPC = 20,	//< PowerPC 
+      EM_PPC64 = 21,	//< PowerPC 64-bit 
+      EM_S390 = 22,	//< IBM S390 
+      EM_V800 = 36,	//< NEC V800 series 
+      EM_FR20 = 37,	//< Fujitsu FR20 
+      EM_RH32 = 38,	//< TRW RH-32 
+      EM_RCE = 39,	//< Motorola RCE 
+      EM_ARM = 40,	//< ARM 
+      EM_FAKE_ALPHA = 41,	//< Digital Alpha 
+      EM_SH = 42,	//< Hitachi SH 
+      EM_SPARCV9 = 43,	//< SPARC v9 64-bit 
+      EM_TRICORE = 44,	//< Siemens Tricore 
+      EM_ARC = 45,	//< Argonaut RISC Core 
+      EM_H8_300 = 46,	//< Hitachi H8/300 
+      EM_H8_300H = 47,	//< Hitachi H8/300H 
+      EM_H8S = 48,	//< Hitachi H8S 
+      EM_H8_500 = 49,	//< Hitachi H8/500 
+      EM_IA_64 = 50,	//< Intel Merced 
+      EM_MIPS_X = 51,	//< Stanford MIPS-X 
+      EM_COLDFIRE = 52,	//< Motorola Coldfire 
+      EM_68HC12 = 53,	//< Motorola M68HC12 
+      EM_MMA = 54,	//< Fujitsu MMA Multimedia Accelerator
+      EM_PCP = 55,	//< Siemens PCP 
+      EM_NCPU = 56,	//< Sony nCPU embeeded RISC 
+      EM_NDR1 = 57,	//< Denso NDR1 microprocessor 
+      EM_STARCORE = 58,	//< Motorola Start*Core processor 
+      EM_ME16 = 59,	//< Toyota ME16 processor 
+      EM_ST100 = 60,	//< STMicroelectronic ST100 processor 
+      EM_TINYJ = 61,	//< Advanced Logic Corp. Tinyj emb.fam
+      EM_X86_64	= 62,	//< AMD x86-64 architecture 
+      EM_PDSP = 63,	//< Sony DSP Processor 
+      EM_FX66 = 66,	//< Siemens FX66 microcontroller 
+      EM_ST9PLUS = 67,	//< STMicroelectronics ST9+ 8/16 mc 
+      EM_ST7 = 68,	//< STmicroelectronics ST7 8 bit mc 
+      EM_68HC16 = 69,	//< Motorola MC68HC16 microcontroller 
+      EM_68HC11 = 70,	//< Motorola MC68HC11 microcontroller 
+      EM_68HC08 = 71,	//< Motorola MC68HC08 microcontroller 
+      EM_68HC05 = 72,	//< Motorola MC68HC05 microcontroller 
+      EM_SVX = 73,	//< Silicon Graphics SVx 
+      EM_ST19 = 74,	//< STMicroelectronics ST19 8 bit mc 
+      EM_VAX = 75,	//< Digital VAX 
+      EM_CRIS = 76,	//< Axis Communications 32-bit embedded processor 
+      EM_JAVELIN = 77,	//< Infineon Technologies 32-bit embedded processor 
+      EM_FIREPATH = 78,	//< Element 14 64-bit DSP Processor 
+      EM_ZSP = 79,	//< LSI Logic 16-bit DSP Processor 
+      EM_MMIX = 80,	//< Donald Knuth's educational 64-bit processor 
+      EM_HUANY = 81,	//< Harvard University machine-independent object files 
+      EM_PRISM = 82,	//< SiTera Prism 
+      EM_AVR = 83,	//< Atmel AVR 8-bit microcontroller 
+      EM_FR30 = 84,	//< Fujitsu FR30 
+      EM_D10V = 85,	//< Mitsubishi D10V 
+      EM_D30V = 86,	//< Mitsubishi D30V 
+      EM_V850 = 87,	//< NEC v850 
+      EM_M32R = 88,	//< Mitsubishi M32R 
+      EM_MN10300 = 89,	//< Matsushita MN10300 
+      EM_MN10200 = 90,	//< Matsushita MN10200 
+      EM_PJ = 91,	//< picoJava 
+      EM_OPENRISC = 92,	//< OpenRISC 32-bit embedded processor 
+      EM_ARC_A5 = 93,	//< ARC Cores Tangent-A5 
+      EM_XTENSA = 94,	//< Tensilica Xtensa Architecture 
+      EM_NUM = 95,
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+      EM_ALPHA = 0x9026,
+    };
+
+  /** Legal values for e_version (version).  */
+
+  static const unsigned int EV_NONE = 0;	//< Invalid ELF version 
+  static const unsigned int EV_CURRENT = 1;	//< Current version 
+  static const unsigned int EV_NUM = 2;
+
+/** 32 bits section header.  */
+struct Elf32_Shdr
+{
+  Elf32_Word    sh_name;	//< Section name (string tbl index) 
+  Elf32_Word    sh_type;	//< Section type 
+  Elf32_Word    sh_flags;	//< Section flags 
+  Elf32_Addr    sh_addr;	//< Section virtual addr at execution 
+  Elf32_Off     sh_offset;	//< Section file offset 
+  Elf32_Word    sh_size;	//< Section size in bytes 
+  Elf32_Word    sh_link;	//< Link to another section 
+  Elf32_Word    sh_info;	//< Additional section information 
+  Elf32_Word    sh_addralign;	//< Section alignment 
+  Elf32_Word    sh_entsize;	//< Entry size if section holds table 
+};
+
+/** 64 bits section header.  */
+struct Elf64_Shdr
+{
+  Elf64_Word    sh_name;	//< Section name (string tbl index) 
+  Elf64_Word    sh_type;	//< Section type 
+  Elf64_Xword   sh_flags;	//< Section flags 
+  Elf64_Addr    sh_addr;	//< Section virtual addr at execution 
+  Elf64_Off     sh_offset;	//< Section file offset 
+  Elf64_Xword   sh_size;	//< Section size in bytes 
+  Elf64_Word    sh_link;	//< Link to another section 
+  Elf64_Word    sh_info;	//< Additional section information 
+  Elf64_Xword   sh_addralign;	//< Section alignment 
+  Elf64_Xword   sh_entsize;	//< Entry size if section holds table 
+};
+
+/** Special section indices.  */
+
+#define SHN_UNDEF       0
+          //< Undefined section 
+#define SHN_LORESERVE   0xff00
+          //< Start of reserved indices 
+#define SHN_LOPROC      0xff00
+          //< Start of processor-specific 
+#define SHN_BEFORE      0xff00
+          //< Order section before all others (Solaris).  
+#define SHN_AFTER       0xff01
+          //< Order section after all others (Solaris).  
+#define SHN_HIPROC      0xff1f
+          //< End of processor-specific 
+#define SHN_LOOS        0xff20
+          //< Start of OS-specific 
+#define SHN_HIOS        0xff3f
+          //< End of OS-specific 
+#define SHN_ABS         0xfff1
+          //< Associated symbol is absolute 
+#define SHN_COMMON      0xfff2
+          //< Associated symbol is common 
+#define SHN_XINDEX      0xffff
+          //< Index is in extra table.  
+#define SHN_HIRESERVE   0xffff
+          //< End of reserved indices 
+
+/** Legal values for sh_type (section type).  */
+
+enum sh_type_e
+  {
+    SHT_NULL = 0,	//< Section header table entry unused 
+    SHT_PROGBITS = 1,	//< Program data 
+    SHT_SYMTAB = 2,	//< Symbol table 
+    SHT_STRTAB = 3,	//< String table 
+    SHT_RELA = 4,	//< Relocation entries with addends 
+    SHT_HASH = 5,	//< Symbol hash table 
+    SHT_DYNAMIC = 6,	//< Dynamic linking information 
+    SHT_NOTE = 7,	//< Notes 
+    SHT_NOBITS = 8,	//< Program space with no data (bss) 
+    SHT_REL = 9,	//< Relocation entries, no addends 
+    SHT_SHLIB = 10,	//< Reserved 
+    SHT_DYNSYM = 11,	//< Dynamic linker symbol table 
+    SHT_INIT_ARRAY = 14,	//< Array of constructors 
+    SHT_FINI_ARRAY = 15,	//< Array of destructors 
+    SHT_PREINIT_ARRAY = 16,	//< Array of pre-constructors 
+    SHT_GROUP = 17,	//< Section group 
+    SHT_SYMTAB_SHNDX = 18,	//< Extended section indeces 
+    SHT_NUM = 19,	//< Number of defined types.  
+    SHT_LOOS = 0x60000000,	//< Start OS-specific.  
+    SHT_GNU_HASH = 0x6ffffff6,	//< GNU-style hash table.  
+    SHT_GNU_LIBLIST = 0x6ffffff7,	//< Prelink library list 
+    SHT_CHECKSUM = 0x6ffffff8,	//< Checksum for DSO content.  
+    SHT_LOSUNW = 0x6ffffffa,	//< Sun-specific low bound.  
+    SHT_SUNW_move = 0x6ffffffa,
+    SHT_SUNW_COMDAT = 0x6ffffffb,
+    SHT_SUNW_syminfo = 0x6ffffffc,
+    SHT_GNU_verdef = 0x6ffffffd,	//< Version definition section.  
+    SHT_GNU_verneed = 0x6ffffffe,	//< Version needs section.  
+    SHT_GNU_versym = 0x6fffffff,	//< Version symbol table.  
+    SHT_HISUNW = 0x6fffffff,	//< Sun-specific high bound.  
+    SHT_HIOS = 0x6fffffff,	//< End OS-specific type 
+    SHT_LOPROC = 0x70000000,	//< Start of processor-specific 
+    SHT_HIPROC = 0x7fffffff,	//< End of processor-specific 
+    SHT_LOUSER = 0x80000000,	//< Start of application-specific 
+    SHT_HIUSER = 0x8fffffff,	//< End of application-specific 
+  };
+
+/** Legal values for sh_flags (section flags).  */
+
+enum sh_flags_e
+  {
+    SHF_NONE =             0,
+    SHF_WRITE =            (1 << 0),	//< Writable 
+    SHF_ALLOC =            (1 << 1),	//< Occupies memory during execution 
+    SHF_EXECINSTR =        (1 << 2),	//< Executable 
+    SHF_MERGE =            (1 << 4),	//< Might be merged 
+    SHF_STRINGS =          (1 << 5),	//< Contains nul-terminated strings 
+    SHF_INFO_LINK =        (1 << 6),	//< `sh_info' contains SHT index 
+    SHF_LINK_ORDER =       (1 << 7),	//< Preserve order after combining 
+    SHF_OS_NONCONFORMING = (1 << 8),	//< Non-standard OS specific handling required 
+    SHF_GROUP =            (1 << 9),	//< Section is member of a group.  
+    SHF_TLS =              (1 << 10),	//< Section hold thread-local data.  
+    SHF_MASKOS =           0x0ff00000,	//< OS-specific.  
+    SHF_MASKPROC =         0xf0000000,	//< Processor-specific 
+    SHF_ORDERED =          (1 << 30),	//< Special ordering requirement (Solaris).  
+    SHF_EXCLUDE =          (1 << 31),	//< Section is excluded unless referenced or allocated (Solaris).
+  };
+
+ELF_ENUM_OPS(sh_flags_e)
+
+/** Section group handling.  */
+static const unsigned int  GRP_COMDAT = 0x1;	//< Mark group as COMDAT.  
+
+/** 32 bits symbol table entry.  */
+struct Elf32_Sym
+{
+  Elf32_Word    st_name;	//< Symbol name (string tbl index) 
+  Elf32_Addr    st_value;	//< Symbol value 
+  Elf32_Word    st_size;	//< Symbol size 
+  unsigned char st_info;	//< Symbol type and binding 
+  unsigned char st_other;	//< Symbol visibility 
+  Elf32_Section st_shndx;	//< Section index 
+};
+
+/** 64 bits symbol table entry.  */
+struct Elf64_Sym
+{
+  Elf64_Word    st_name;	//< Symbol name (string tbl index) 
+  unsigned char st_info;	//< Symbol type and binding 
+  unsigned char st_other;	//< Symbol visibility 
+  Elf64_Section st_shndx;	//< Section index 
+  Elf64_Addr    st_value;	//< Symbol value 
+  Elf64_Xword   st_size;	//< Symbol size 
+};
+
+/** 32 bits syminfo section if available contains additional information about every dynamic symbol.  */
+struct Elf32_Syminfo
+{
+  Elf32_Half si_boundto;	//< Direct bindings, symbol bound to 
+  Elf32_Half si_flags;	//< Per symbol flags 
+};
+
+/** 64 bits syminfo section if available contains additional information about every dynamic symbol.  */
+struct Elf64_Syminfo
+{
+  Elf64_Half si_boundto;	//< Direct bindings, symbol bound to 
+  Elf64_Half si_flags;	//< Per symbol flags 
+};
+
+/** Possible values for si_boundto.  */
+enum si_boundto_e
+  {
+    SYMINFO_BT_SELF =         0xffff,	//< Symbol bound to self 
+    SYMINFO_BT_PARENT =       0xfffe,	//< Symbol bound to parent 
+    SYMINFO_BT_LOWRESERVE =   0xff00,	//< Beginning of reserved entries 
+  };
+
+/** Possible bitmasks for si_flags.  */
+enum si_flags_e
+  {
+    SYMINFO_FLG_DIRECT =      0x0001,	//< Direct bound symbol 
+    SYMINFO_FLG_PASSTHRU =    0x0002,	//< Pass-thru symbol for translator 
+    SYMINFO_FLG_COPY =        0x0004,	//< Symbol is a copy-reloc 
+    SYMINFO_FLG_LAZYLOAD =    0x0008,	//< Symbol bound to object to be lazy loaded 
+  };
+
+/** Syminfo version values.  */
+enum si_version_e {
+    SYMINFO_NONE = 0,
+    SYMINFO_CURRENT = 1,
+    SYMINFO_NUM = 2,
+  };
+
+/** Extract bind information held in the st_info field.  */
+#define ELF_ST_BIND(val)              ((::elfpp::st_info_bind_e)(((unsigned char) (val)) >> 4))
+/** Extract type information held in the st_info field.  */
+#define ELF_ST_TYPE(val)              ((::elfpp::st_info_type_e)((val) & 0xf))
+/** Insert information held in the st_info field.  */
+#define ELF_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
+
+/** Legal values for ST_BIND subfield of st_info (symbol binding).  */
+enum st_info_bind_e
+  {
+    STB_LOCAL =       0,	//< Local symbol 
+    STB_GLOBAL =      1,	//< Global symbol 
+    STB_WEAK =        2,	//< Weak symbol 
+    STB_NUM =         3,	//< Number of defined types.  
+    STB_LOOS =        10,	//< Start of OS-specific 
+    STB_HIOS =        12,	//< End of OS-specific 
+    STB_LOPROC =      13,	//< Start of processor-specific 
+    STB_HIPROC =      15,	//< End of processor-specific 
+  };
+
+/** Legal values for ST_TYPE subfield of st_info (symbol type).  */
+enum st_info_type_e
+  {
+    STT_NOTYPE =      0,	//< Symbol type is unspecified 
+    STT_OBJECT =      1,	//< Symbol is a data object 
+    STT_FUNC =        2,	//< Symbol is a code object 
+    STT_SECTION =     3,	//< Symbol associated with a section 
+    STT_FILE =        4,	//< Symbol's name is file name 
+    STT_COMMON =      5,	//< Symbol is a common data object 
+    STT_TLS =         6,	//< Symbol is thread-local data object
+    STT_NUM =         7,	//< Number of defined types.  
+    STT_LOOS =        10,	//< Start of OS-specific 
+    STT_HIOS =        12,	//< End of OS-specific 
+    STT_LOPROC =      13,	//< Start of processor-specific 
+    STT_HIPROC =      15,	//< End of processor-specific 
+  };
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+static const unsigned int STN_UNDEF = 0;	//< End of a chain.  
+
+/** @multiple How to extract and insert information held in the st_other field.  */
+
+#define ELF32_ST_VISIBILITY(o)  ((o) & 0x03)
+#define ELF64_ST_VISIBILITY(o)  ELF32_ST_VISIBILITY (o)
+
+/** Symbol visibility specification encoded in the st_other field.  */
+enum st_other_e
+  {
+    STV_DEFAULT =     0,	//< Default symbol visibility rules 
+    STV_INTERNAL =    1,	//< Processor specific hidden class 
+    STV_HIDDEN =      2,	//< Sym unavailable in other modules 
+    STV_PROTECTED =   3,	//< Not preemptible, not exported 
+  };
+
+/** Relocation table entry without addend (in section of type SHT_REL).  */
+struct Elf32_Rel
+{
+  Elf32_Addr    r_offset;	//< Address 
+  Elf32_Word    r_info;	//< Relocation type and symbol index 
+};
+
+/* I have seen two different definitions of the Elf64_Rel and
+   Elf64_Rela structures, so we'll leave them out until Novell (or
+   whoever) gets their act together.  */
+/** The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
+
+struct Elf64_Rel
+{
+  Elf64_Addr    r_offset;	//< Address 
+  Elf64_Xword   r_info;	//< Relocation type and symbol index 
+};
+
+/** @multiple Relocation table entry with addend (in section of type SHT_RELA).  */
+
+struct Elf32_Rela
+{
+  Elf32_Addr    r_offset;	//< Address 
+  Elf32_Word    r_info;	//< Relocation type and symbol index 
+  Elf32_Sword   r_addend;	//< Addend 
+};
+
+struct Elf64_Rela
+{
+  Elf64_Addr    r_offset;	//< Address 
+  Elf64_Xword   r_info;	//< Relocation type and symbol index 
+  Elf64_Sxword  r_addend;	//< Addend 
+};
+
+/** @multiple @showcontent How to extract and insert information held in the @tt r_info field.  */
+
+#define ELF32_R_SYM(val)                ((val) >> 8)
+#define ELF32_R_TYPE(val)               ((val) & 0xff)
+#define ELF32_R_INFO(sym, type)         (((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)                  ((i) >> 32)
+#define ELF64_R_TYPE(i)                 ((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)          ((((Elf64_Xword) (sym)) << 32) + (type))
+
+/** @multiple Program segment header.  */
+
+struct Elf32_Phdr
+{
+  Elf32_Word    p_type;	//< Segment type 
+  Elf32_Off     p_offset;	//< Segment file offset 
+  Elf32_Addr    p_vaddr;	//< Segment virtual address 
+  Elf32_Addr    p_paddr;	//< Segment physical address 
+  Elf32_Word    p_filesz;	//< Segment size in file 
+  Elf32_Word    p_memsz;	//< Segment size in memory 
+  Elf32_Word    p_flags;	//< Segment flags 
+  Elf32_Word    p_align;	//< Segment alignment 
+};
+
+struct Elf64_Phdr
+{
+  Elf64_Word    p_type;	//< Segment type 
+  Elf64_Word    p_flags;	//< Segment flags 
+  Elf64_Off     p_offset;	//< Segment file offset 
+  Elf64_Addr    p_vaddr;	//< Segment virtual address 
+  Elf64_Addr    p_paddr;	//< Segment physical address 
+  Elf64_Xword   p_filesz;	//< Segment size in file 
+  Elf64_Xword   p_memsz;	//< Segment size in memory 
+  Elf64_Xword   p_align;	//< Segment alignment 
+};
+
+/** Legal values for p_type (segment type).  */
+
+enum p_type_e
+  {
+    PT_NULL =         0,	//< Program header table entry unused 
+    PT_LOAD =         1,	//< Loadable program segment 
+    PT_DYNAMIC =      2,	//< Dynamic linking information 
+    PT_INTERP =       3,	//< Program interpreter 
+    PT_NOTE =         4,	//< Auxiliary information 
+    PT_SHLIB =        5,	//< Reserved 
+    PT_PHDR =         6,	//< Entry for header table itself 
+    PT_TLS =          7,	//< Thread-local storage segment 
+    PT_NUM =          8,	//< Number of defined types 
+    PT_LOOS =         0x60000000,	//< Start of OS-specific 
+    PT_GNU_EH_FRAME = 0x6474e550,	//< GCC .eh_frame_hdr segment 
+    PT_GNU_STACK =    0x6474e551,	//< Indicates stack executability 
+    PT_GNU_RELRO =    0x6474e552,	//< Read-only after relocation 
+    PT_LOSUNW =       0x6ffffffa,
+    PT_SUNWBSS =      0x6ffffffa,	//< Sun Specific segment 
+    PT_SUNWSTACK =    0x6ffffffb,	//< Stack segment 
+    PT_HISUNW =       0x6fffffff,
+    PT_HIOS =         0x6fffffff,	//< End of OS-specific 
+    PT_LOPROC =       0x70000000,	//< Start of processor-specific 
+    PT_HIPROC =       0x7fffffff,	//< End of processor-specific 
+  };
+
+/** Legal values for p_flags (segment flags).  */
+
+enum p_flags_e
+  {
+    PF_X =            (1 << 0),	//< Segment is executable 
+    PF_W =            (1 << 1),	//< Segment is writable 
+    PF_R =            (1 << 2),	//< Segment is readable 
+    PF_MASKOS =       0x0ff00000,	//< OS-specific 
+    PF_MASKPROC =     0xf0000000,	//< Processor-specific 
+  };
+
+/** Legal values for note segment descriptor types for core files. */
+
+enum note_desc_type_e
+  {
+    NT_PRSTATUS =     1,	//< Contains copy of prstatus struct 
+    NT_FPREGSET =     2,	//< Contains copy of fpregset struct 
+    NT_PRPSINFO =     3,	//< Contains copy of prpsinfo struct 
+    NT_PRXREG =       4,	//< Contains copy of prxregset struct 
+    NT_TASKSTRUCT =   4,	//< Contains copy of task structure 
+    NT_PLATFORM =     5,	//< String from sysinfo(SI_PLATFORM) 
+    NT_AUXV =         6,	//< Contains copy of auxv array 
+    NT_GWINDOWS =     7,	//< Contains copy of gwindows struct 
+    NT_ASRS =         8,	//< Contains copy of asrset struct 
+    NT_PSTATUS =      10,	//< Contains copy of pstatus struct 
+    NT_PSINFO =       13,	//< Contains copy of psinfo struct 
+    NT_PRCRED =       14,	//< Contains copy of prcred struct 
+    NT_UTSNAME =      15,	//< Contains copy of utsname struct 
+    NT_LWPSTATUS =    16,	//< Contains copy of lwpstatus struct 
+    NT_LWPSINFO =     17,	//< Contains copy of lwpinfo struct 
+    NT_PRFPXREG =     20,	//< Contains copy of fprxregset struct
+    NT_PRXFPREG =     0x46e62b7f,	//< Contains copy of user_fxsr_struct
+
+    NT_VERSION =      1,	//< Contains a version string.  
+  };
+
+/** Version definition sections.  */
+
+struct Elf32_Verdef
+{
+  Elf32_Half    vd_version;	//< Version revision 
+  Elf32_Half    vd_flags;	//< Version information 
+  Elf32_Half    vd_ndx;	//< Version Index 
+  Elf32_Half    vd_cnt;	//< Number of associated aux entries 
+  Elf32_Word    vd_hash;	//< Version name hash value 
+  Elf32_Word    vd_aux;	//< Offset in bytes to verdaux array 
+  Elf32_Word    vd_next;	//< Offset in bytes to next verdef entry
+};
+
+struct Elf64_Verdef
+{
+  Elf64_Half    vd_version;	//< Version revision 
+  Elf64_Half    vd_flags;	//< Version information 
+  Elf64_Half    vd_ndx;	//< Version Index 
+  Elf64_Half    vd_cnt;	//< Number of associated aux entries 
+  Elf64_Word    vd_hash;	//< Version name hash value 
+  Elf64_Word    vd_aux;	//< Offset in bytes to verdaux array 
+  Elf64_Word    vd_next;	//< Offset in bytes to next verdef entry
+};
+
+
+/** Legal values for vd_version (version revision).  */
+enum vd_version_e
+  {
+    VER_DEF_NONE =    0,	//< No version 
+    VER_DEF_CURRENT = 1,	//< Current version 
+    VER_DEF_NUM =     2,	//< Given version number 
+  };
+
+/** Legal values for vd_flags (version information flags).  */
+enum vd_flags
+  {
+    VER_FLG_BASE =    0x1,	//< Version definition of file itself 
+    VER_FLG_WEAK =    0x2,	//< Weak version identifier 
+  };
+
+/** Versym symbol index values.  */
+enum ver_ndx_e
+  {
+    VER_NDX_LOCAL =           0,	//< Symbol is local.  
+    VER_NDX_GLOBAL =          1,	//< Symbol is global.  
+    VER_NDX_LORESERVE =       0xff00,	//< Beginning of reserved entries.  
+    VER_NDX_ELIMINATE =       0xff01,	//< Symbol is to be eliminated.  
+  };
+
+/** Auxialiary version information.  */
+
+struct Elf32_Verdaux
+{
+  Elf32_Word    vda_name;	//< Version or dependency names 
+  Elf32_Word    vda_next;	//< Offset in bytes to next verdaux entry
+};
+
+struct Elf64_Verdaux
+{
+  Elf64_Word    vda_name;	//< Version or dependency names 
+  Elf64_Word    vda_next;	//< Offset in bytes to next verdaux entry
+};
+
+
+/** Version dependency section.  */
+
+struct Elf32_Verneed
+{
+  Elf32_Half    vn_version;	//< Version of structure 
+  Elf32_Half    vn_cnt;	//< Number of associated aux entries 
+  Elf32_Word    vn_file;	//< Offset of filename for this dependency
+  Elf32_Word    vn_aux;	//< Offset in bytes to vernaux array 
+  Elf32_Word    vn_next;	//< Offset in bytes to next verneed entry
+};
+
+struct Elf64_Verneed
+{
+  Elf64_Half    vn_version;	//< Version of structure 
+  Elf64_Half    vn_cnt;	//< Number of associated aux entries 
+  Elf64_Word    vn_file;	//< Offset of filename for this dependency
+  Elf64_Word    vn_aux;	//< Offset in bytes to vernaux array 
+  Elf64_Word    vn_next;	//< Offset in bytes to next verneed entry
+};
+
+
+/** Legal values for vn_version (version revision).  */
+enum vn_version_e
+  {
+    VER_NEED_NONE =    0,	//< No version 
+    VER_NEED_CURRENT = 1,	//< Current version 
+    VER_NEED_NUM =     2,	//< Given version number 
+  };
+
+/** Auxiliary needed version information.  */
+
+struct Elf32_Vernaux
+{
+  Elf32_Word    vna_hash;	//< Hash value of dependency name 
+  Elf32_Half    vna_flags;	//< Dependency specific information 
+  Elf32_Half    vna_other;	//< Unused 
+  Elf32_Word    vna_name;	//< Dependency name string offset 
+  Elf32_Word    vna_next;	//< Offset in bytes to next vernaux entry
+};
+
+struct Elf64_Vernaux
+{
+  Elf64_Word    vna_hash;	//< Hash value of dependency name 
+  Elf64_Half    vna_flags;	//< Dependency specific information 
+  Elf64_Half    vna_other;	//< Unused 
+  Elf64_Word    vna_name;	//< Dependency name string offset 
+  Elf64_Word    vna_next;	//< Offset in bytes to next vernaux entry
+};
+
+/* Auxiliary vector.  */
+
+/** @multiple This vector is normally only used by the program interpreter.  The
+   usual definition in an ABI supplement uses the name auxv_t.  The
+   vector is not usually defined in a standard <elf.h> file, but it
+   can't hurt.  We rename it to avoid conflicts.  The sizes of these
+   types are an arrangement between the exec server and the program
+   interpreter, so we don't fully specify them here.  */
+
+struct Elf32_auxv_t
+{
+  uint32_t a_type;	//< Entry type 
+  union
+    {
+      uint32_t a_val;	//< Integer value 
+      /** We use to have pointer elements added here.  We cannot do that,
+         though, since it does not work when using 32-bit definitions
+         on 64-bit platforms and vice versa.  */
+    } a_un;
+};
+
+struct Elf64_auxv_t
+{
+  uint64_t a_type;	//< Entry type 
+  union
+    {
+      uint64_t a_val;	//< Integer value 
+      /** We use to have pointer elements added here.  We cannot do that,
+         though, since it does not work when using 32-bit definitions
+         on 64-bit platforms and vice versa.  */
+    } a_un;
+};
+
+/** Legal values for a_type (entry type).  */
+
+enum a_type_e
+  {
+    AT_NULL =         0,	//< End of vector 
+    AT_IGNORE =       1,	//< Entry should be ignored 
+    AT_EXECFD =       2,	//< File descriptor of program 
+    AT_PHDR =         3,	//< Program headers for program 
+    AT_PHENT =        4,	//< Size of program header entry 
+    AT_PHNUM =        5,	//< Number of program headers 
+    AT_PAGESZ =       6,	//< System page size 
+    AT_BASE =         7,	//< Base address of interpreter 
+    AT_FLAGS =        8,	//< Flags 
+    AT_ENTRY =        9,	//< Entry point of program 
+    AT_NOTELF =       10,	//< Program is not ELF 
+    AT_UID =          11,	//< Real uid 
+    AT_EUID =         12,	//< Effective uid 
+    AT_GID =          13,	//< Real gid 
+    AT_EGID =         14,	//< Effective gid 
+    AT_CLKTCK =       17,	//< Frequency of times() 
+
+    /** Some more special a_type values describing the hardware.  */
+    AT_PLATFORM =     15,	//< String identifying platform.  
+    AT_HWCAP =        16,	//< Machine dependent hints about processor capabilities.  
+  };
+
+/** This entry gives some information about the FPU initialization
+   performed by the kernel.  */
+#define AT_FPUCW        18              /** Used FPU control word.  */
+
+/* Cache block sizes.  */
+#define AT_DCACHEBSIZE  19              
+              //< Data cache block size
+#define AT_ICACHEBSIZE  20
+              //< Instruction cache block size.
+#define AT_UCACHEBSIZE  21              
+             //< Unified cache block size.
+
+/* A special ignored value for PPC, used by the kernel to control the
+   interpretation of the AUXV. Must be > 16.  */
+
+#define AT_IGNOREPPC    22
+            //< Entry should be ignored.
+#define AT_SECURE       23              
+            //< Boolean, was exec setuid-like?
+
+/** @multiple Pointer to the global system page used for system calls and other nice things.  */
+#define AT_SYSINFO      32
+#define AT_SYSINFO_EHDR 33
+
+/** @multiple Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
+   log2 of line size; mask those to get cache size.  */
+#define AT_L1I_CACHESHAPE       34
+#define AT_L1D_CACHESHAPE       35
+#define AT_L2_CACHESHAPE        36
+#define AT_L3_CACHESHAPE        37
+
+/** @multiple  Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+struct Elf32_Nhdr
+{
+  Elf32_Word n_namesz;	//< Length of the note's name.  
+  Elf32_Word n_descsz;	//< Length of the note's descriptor.  
+  Elf32_Word n_type;	//< Type of the note.  
+};
+
+struct Elf64_Nhdr
+{
+  Elf64_Word n_namesz;	//< Length of the note's name.  
+  Elf64_Word n_descsz;	//< Length of the note's descriptor.  
+  Elf64_Word n_type;	//< Type of the note.  
+};
+
+/* Known names of notes.  */
+
+/** Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS        "SUNW Solaris"
+
+/** Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU            "GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/** Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT  1
+
+
+/* Defined note types for GNU systems.  */
+
+/** ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define ELF_NOTE_ABI            1
+
+/** Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
+   note section entry.  */
+#define ELF_NOTE_OS_LINUX       0
+#define ELF_NOTE_OS_GNU         1
+#define ELF_NOTE_OS_SOLARIS2    2
+#define ELF_NOTE_OS_FREEBSD     3
+
+
+/** @multiple Move records.  */
+struct Elf32_Move
+{
+  Elf32_Xword m_value;	//< Symbol value.  
+  Elf32_Word m_info;	//< Size and index.  
+  Elf32_Word m_poffset;	//< Symbol offset.  
+  Elf32_Half m_repeat;	//< Repeat count.  
+  Elf32_Half m_stride;	//< Stride info.  
+};
+
+struct Elf64_Move
+{
+  Elf64_Xword m_value;	//< Symbol value.  
+  Elf64_Xword m_info;	//< Size and index.  
+  Elf64_Xword m_poffset;//< Symbol offset.  
+  Elf64_Half m_repeat;	//< Repeat count.  
+  Elf64_Half m_stride;	//< Stride info.  
+};
+
+/** @multiple Macro to construct move records.  */
+#define ELF32_M_SYM(info)       ((info) >> 8)
+#define ELF32_M_SIZE(info)      ((unsigned char) (info))
+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)       ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)      ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size)
+
+/** Motorola 68k specific definitions.  */
+
+/** Values for Elf32_Ehdr.e_flags.  */
+#define EF_CPU32        0x00810000
+
+/** Relocation ids */
+
+enum reloc_e
+  {
+    R_NONE =      0,	//< No reloc 
+
+    /* m68k relocs.  */
+    R_68K_NONE =      0,	//< No reloc 
+    R_68K_32 =        1,	//< Direct 32 bit  
+    R_68K_16 =        2,	//< Direct 16 bit  
+    R_68K_8 =         3,	//< Direct 8 bit  
+    R_68K_PC32 =      4,	//< PC relative 32 bit 
+    R_68K_PC16 =      5,	//< PC relative 16 bit 
+    R_68K_PC8 =       6,	//< PC relative 8 bit 
+    R_68K_GOT32 =     7,	//< 32 bit PC relative GOT entry 
+    R_68K_GOT16 =     8,	//< 16 bit PC relative GOT entry 
+    R_68K_GOT8 =      9,	//< 8 bit PC relative GOT entry 
+    R_68K_GOT32O =    10,	//< 32 bit GOT offset 
+    R_68K_GOT16O =    11,	//< 16 bit GOT offset 
+    R_68K_GOT8O =     12,	//< 8 bit GOT offset 
+    R_68K_PLT32 =     13,	//< 32 bit PC relative PLT address 
+    R_68K_PLT16 =     14,	//< 16 bit PC relative PLT address 
+    R_68K_PLT8 =      15,	//< 8 bit PC relative PLT address 
+    R_68K_PLT32O =    16,	//< 32 bit PLT offset 
+    R_68K_PLT16O =    17,	//< 16 bit PLT offset 
+    R_68K_PLT8O =     18,	//< 8 bit PLT offset 
+    R_68K_COPY =      19,	//< Copy symbol at runtime 
+    R_68K_GLOB_DAT =  20,	//< Create GOT entry 
+    R_68K_JMP_SLOT =  21,	//< Create PLT entry 
+    R_68K_RELATIVE =  22,	//< Adjust by program base 
+/* Keep this the last entry.  */
+    R_68K_NUM =       23,
+
+    /* i386 relocs.  */
+    R_386_NONE =         0,	//< No reloc 
+    R_386_32 =           1,	//< Direct 32 bit  
+    R_386_PC32 =         2,	//< PC relative 32 bit 
+    R_386_GOT32 =        3,	//< 32 bit GOT entry 
+    R_386_PLT32 =        4,	//< 32 bit PLT address 
+    R_386_COPY =         5,	//< Copy symbol at runtime 
+    R_386_GLOB_DAT =     6,	//< Create GOT entry 
+    R_386_JMP_SLOT =     7,	//< Create PLT entry 
+    R_386_RELATIVE =     8,	//< Adjust by program base 
+    R_386_GOTOFF =       9,	//< 32 bit offset to GOT 
+    R_386_GOTPC =        10,	//< 32 bit PC relative offset to GOT 
+    R_386_32PLT =        11,
+    R_386_TLS_TPOFF =    14,	//< Offset in static TLS block 
+    R_386_TLS_IE =       15,	//< Address of GOT entry for static TLS block offset 
+    R_386_TLS_GOTIE =    16,	//< GOT entry for static TLS block offset 
+    R_386_TLS_LE =       17,	//< Offset relative to static TLS block 
+    R_386_TLS_GD =       18,	//< Direct 32 bit for GNU version of general dynamic thread local data 
+    R_386_TLS_LDM =      19,	//< Direct 32 bit for GNU version of local dynamic thread local data in LE code 
+    R_386_16 =           20,
+    R_386_PC16 =         21,
+    R_386_8 =            22,
+    R_386_PC8 =          23,
+    R_386_TLS_GD_32 =    24,	//< Direct 32 bit for general dynamic thread local data 
+    R_386_TLS_GD_PUSH =  25,	//< Tag for pushl in GD TLS code 
+    R_386_TLS_GD_CALL =  26,	//< Relocation for call to __tls_get_addr() 
+    R_386_TLS_GD_POP =   27,	//< Tag for popl in GD TLS code 
+    R_386_TLS_LDM_32 =   28,	//< Direct 32 bit for local dynamic thread local data in LE code 
+    R_386_TLS_LDM_PUSH = 29,	//< Tag for pushl in LDM TLS code 
+    R_386_TLS_LDM_CALL = 30,	//< Relocation for call to __tls_get_addr() in LDM code 
+    R_386_TLS_LDM_POP =  31,	//< Tag for popl in LDM TLS code 
+    R_386_TLS_LDO_32 =   32,	//< Offset relative to TLS block 
+    R_386_TLS_IE_32 =    33,	//< GOT entry for negated static TLS block offset 
+    R_386_TLS_LE_32 =    34,	//< Negated offset relative to static TLS block 
+    R_386_TLS_DTPMOD32 = 35,	//< ID of module containing symbol 
+    R_386_TLS_DTPOFF32 = 36,	//< Offset in TLS block 
+    R_386_TLS_TPOFF32 =  37,	//< Negated offset in static TLS block 
+/* Keep this the last entry.  */
+    R_386_NUM =          38,
+
+    /* SPARC relocs.  */
+    R_SPARC_NONE =            0,	//< No reloc 
+    R_SPARC_8 =               1,	//< Direct 8 bit 
+    R_SPARC_16 =              2,	//< Direct 16 bit 
+    R_SPARC_32 =              3,	//< Direct 32 bit 
+    R_SPARC_DISP8 =           4,	//< PC relative 8 bit 
+    R_SPARC_DISP16 =          5,	//< PC relative 16 bit 
+    R_SPARC_DISP32 =          6,	//< PC relative 32 bit 
+    R_SPARC_WDISP30 =         7,	//< PC relative 30 bit shifted 
+    R_SPARC_WDISP22 =         8,	//< PC relative 22 bit shifted 
+    R_SPARC_HI22 =            9,	//< High 22 bit 
+    R_SPARC_22 =              10,	//< Direct 22 bit 
+    R_SPARC_13 =              11,	//< Direct 13 bit 
+    R_SPARC_LO10 =            12,	//< Truncated 10 bit 
+    R_SPARC_GOT10 =           13,	//< Truncated 10 bit GOT entry 
+    R_SPARC_GOT13 =           14,	//< 13 bit GOT entry 
+    R_SPARC_GOT22 =           15,	//< 22 bit GOT entry shifted 
+    R_SPARC_PC10 =            16,	//< PC relative 10 bit truncated 
+    R_SPARC_PC22 =            17,	//< PC relative 22 bit shifted 
+    R_SPARC_WPLT30 =          18,	//< 30 bit PC relative PLT address 
+    R_SPARC_COPY =            19,	//< Copy symbol at runtime 
+    R_SPARC_GLOB_DAT =        20,	//< Create GOT entry 
+    R_SPARC_JMP_SLOT =        21,	//< Create PLT entry 
+    R_SPARC_RELATIVE =        22,	//< Adjust by program base 
+    R_SPARC_UA32 =            23,	//< Direct 32 bit unaligned 
+
+    /* Additional Sparc64 relocs.  */
+    R_SPARC_PLT32 =           24,	//< Direct 32 bit ref to PLT entry 
+    R_SPARC_HIPLT22 =         25,	//< High 22 bit PLT entry 
+    R_SPARC_LOPLT10 =         26,	//< Truncated 10 bit PLT entry 
+    R_SPARC_PCPLT32 =         27,	//< PC rel 32 bit ref to PLT entry 
+    R_SPARC_PCPLT22 =         28,	//< PC rel high 22 bit PLT entry 
+    R_SPARC_PCPLT10 =         29,	//< PC rel trunc 10 bit PLT entry 
+    R_SPARC_10 =              30,	//< Direct 10 bit 
+    R_SPARC_11 =              31,	//< Direct 11 bit 
+    R_SPARC_64 =              32,	//< Direct 64 bit 
+    R_SPARC_OLO10 =           33,	//< 10bit with secondary 13bit addend 
+    R_SPARC_HH22 =            34,	//< Top 22 bits of direct 64 bit 
+    R_SPARC_HM10 =            35,	//< High middle 10 bits of ... 
+    R_SPARC_LM22 =            36,	//< Low middle 22 bits of ... 
+    R_SPARC_PC_HH22 =         37,	//< Top 22 bits of pc rel 64 bit 
+    R_SPARC_PC_HM10 =         38,	//< High middle 10 bit of ... 
+    R_SPARC_PC_LM22 =         39,	//< Low miggle 22 bits of ... 
+    R_SPARC_WDISP16 =         40,	//< PC relative 16 bit shifted 
+    R_SPARC_WDISP19 =         41,	//< PC relative 19 bit shifted 
+    R_SPARC_7 =               43,	//< Direct 7 bit 
+    R_SPARC_5 =               44,	//< Direct 5 bit 
+    R_SPARC_6 =               45,	//< Direct 6 bit 
+    R_SPARC_DISP64 =          46,	//< PC relative 64 bit 
+    R_SPARC_PLT64 =           47,	//< Direct 64 bit ref to PLT entry 
+    R_SPARC_HIX22 =           48,	//< High 22 bit complemented 
+    R_SPARC_LOX10 =           49,	//< Truncated 11 bit complemented 
+    R_SPARC_H44 =             50,	//< Direct high 12 of 44 bit 
+    R_SPARC_M44 =             51,	//< Direct mid 22 of 44 bit 
+    R_SPARC_L44 =             52,	//< Direct low 10 of 44 bit 
+    R_SPARC_REGISTER =        53,	//< Global register usage 
+    R_SPARC_UA64 =            54,	//< Direct 64 bit unaligned 
+    R_SPARC_UA16 =            55,	//< Direct 16 bit unaligned 
+    R_SPARC_TLS_GD_HI22 =     56,
+    R_SPARC_TLS_GD_LO10 =     57,
+    R_SPARC_TLS_GD_ADD =      58,
+    R_SPARC_TLS_GD_CALL =     59,
+    R_SPARC_TLS_LDM_HI22 =    60,
+    R_SPARC_TLS_LDM_LO10 =    61,
+    R_SPARC_TLS_LDM_ADD =     62,
+    R_SPARC_TLS_LDM_CALL =    63,
+    R_SPARC_TLS_LDO_HIX22 =   64,
+    R_SPARC_TLS_LDO_LOX10 =   65,
+    R_SPARC_TLS_LDO_ADD =     66,
+    R_SPARC_TLS_IE_HI22 =     67,
+    R_SPARC_TLS_IE_LO10 =     68,
+    R_SPARC_TLS_IE_LD =       69,
+    R_SPARC_TLS_IE_LDX =      70,
+    R_SPARC_TLS_IE_ADD =      71,
+    R_SPARC_TLS_LE_HIX22 =    72,
+    R_SPARC_TLS_LE_LOX10 =    73,
+    R_SPARC_TLS_DTPMOD32 =    74,
+    R_SPARC_TLS_DTPMOD64 =    75,
+    R_SPARC_TLS_DTPOFF32 =    76,
+    R_SPARC_TLS_DTPOFF64 =    77,
+    R_SPARC_TLS_TPOFF32 =     78,
+    R_SPARC_TLS_TPOFF64 =     79,
+/* Keep this the last entry.  */
+    R_SPARC_NUM =             80,
+
+    /* MIPS relocs.  */
+    R_MIPS_NONE =             0,	//< No reloc 
+    R_MIPS_16 =               1,	//< Direct 16 bit 
+    R_MIPS_32 =               2,	//< Direct 32 bit 
+    R_MIPS_REL32 =            3,	//< PC relative 32 bit 
+    R_MIPS_26 =               4,	//< Direct 26 bit shifted 
+    R_MIPS_HI16 =             5,	//< High 16 bit 
+    R_MIPS_LO16 =             6,	//< Low 16 bit 
+    R_MIPS_GPREL16 =          7,	//< GP relative 16 bit 
+    R_MIPS_LITERAL =          8,	//< 16 bit literal entry 
+    R_MIPS_GOT16 =            9,	//< 16 bit GOT entry 
+    R_MIPS_PC16 =             10,	//< PC relative 16 bit 
+    R_MIPS_CALL16 =           11,	//< 16 bit GOT entry for function 
+    R_MIPS_GPREL32 =          12,	//< GP relative 32 bit 
+    R_MIPS_SHIFT5 =           16,
+    R_MIPS_SHIFT6 =           17,
+    R_MIPS_64 =               18,
+    R_MIPS_GOT_DISP =         19,
+    R_MIPS_GOT_PAGE =         20,
+    R_MIPS_GOT_OFST =         21,
+    R_MIPS_GOT_HI16 =         22,
+    R_MIPS_GOT_LO16 =         23,
+    R_MIPS_SUB =              24,
+    R_MIPS_INSERT_A =         25,
+    R_MIPS_INSERT_B =         26,
+    R_MIPS_DELETE =           27,
+    R_MIPS_HIGHER =           28,
+    R_MIPS_HIGHEST =          29,
+    R_MIPS_CALL_HI16 =        30,
+    R_MIPS_CALL_LO16 =        31,
+    R_MIPS_SCN_DISP =         32,
+    R_MIPS_REL16 =            33,
+    R_MIPS_ADD_IMMEDIATE =    34,
+    R_MIPS_PJUMP =            35,
+    R_MIPS_RELGOT =           36,
+    R_MIPS_JALR =             37,
+    R_MIPS_TLS_DTPMOD32 =     38,	//< Module number 32 bit 
+    R_MIPS_TLS_DTPREL32 =     39,	//< Module-relative offset 32 bit 
+    R_MIPS_TLS_DTPMOD64 =     40,	//< Module number 64 bit 
+    R_MIPS_TLS_DTPREL64 =     41,	//< Module-relative offset 64 bit 
+    R_MIPS_TLS_GD =           42,	//< 16 bit GOT offset for GD 
+    R_MIPS_TLS_LDM =          43,	//< 16 bit GOT offset for LDM 
+    R_MIPS_TLS_DTPREL_HI16 =  44,	//< Module-relative offset, high 16 bits 
+    R_MIPS_TLS_DTPREL_LO16 =  45,	//< Module-relative offset, low 16 bits 
+    R_MIPS_TLS_GOTTPREL =     46,	//< 16 bit GOT offset for IE 
+    R_MIPS_TLS_TPREL32 =      47,	//< TP-relative offset, 32 bit 
+    R_MIPS_TLS_TPREL64 =      48,	//< TP-relative offset, 64 bit 
+    R_MIPS_TLS_TPREL_HI16 =   49,	//< TP-relative offset, high 16 bits 
+    R_MIPS_TLS_TPREL_LO16 =   50,	//< TP-relative offset, low 16 bits 
+    R_MIPS_GLOB_DAT =         51,
+    /* Keep this the last entry.  */
+    R_MIPS_NUM =              52,
+
+/* HPPA relocs.  */
+
+    R_PARISC_NONE =           0,	//< No reloc.  
+    R_PARISC_DIR32 =          1,	//< Direct 32-bit reference.  
+    R_PARISC_DIR21L =         2,	//< Left 21 bits of eff. address.  
+    R_PARISC_DIR17R =         3,	//< Right 17 bits of eff. address.  
+    R_PARISC_DIR17F =         4,	//< 17 bits of eff. address.  
+    R_PARISC_DIR14R =         6,	//< Right 14 bits of eff. address.  
+    R_PARISC_PCREL32 =        9,	//< 32-bit rel. address.  
+    R_PARISC_PCREL21L =       10,	//< Left 21 bits of rel. address.  
+    R_PARISC_PCREL17R =       11,	//< Right 17 bits of rel. address.  
+    R_PARISC_PCREL17F =       12,	//< 17 bits of rel. address.  
+    R_PARISC_PCREL14R =       14,	//< Right 14 bits of rel. address.  
+    R_PARISC_DPREL21L =       18,	//< Left 21 bits of rel. address.  
+    R_PARISC_DPREL14R =       22,	//< Right 14 bits of rel. address.  
+    R_PARISC_GPREL21L =       26,	//< GP-relative, left 21 bits.  
+    R_PARISC_GPREL14R =       30,	//< GP-relative, right 14 bits.  
+    R_PARISC_LTOFF21L =       34,	//< LT-relative, left 21 bits.  
+    R_PARISC_LTOFF14R =       38,	//< LT-relative, right 14 bits.  
+    R_PARISC_SECREL32 =       41,	//< 32 bits section rel. address.  
+    R_PARISC_SEGBASE =        48,	//< No relocation, set segment base.  
+    R_PARISC_SEGREL32 =       49,	//< 32 bits segment rel. address.  
+    R_PARISC_PLTOFF21L =      50,	//< PLT rel. address, left 21 bits.  
+    R_PARISC_PLTOFF14R =      54,	//< PLT rel. address, right 14 bits.  
+    R_PARISC_LTOFF_FPTR32 =   57,	//< 32 bits LT-rel. function pointer. 
+    R_PARISC_LTOFF_FPTR21L =  58,	//< LT-rel. fct ptr, left 21 bits. 
+    R_PARISC_LTOFF_FPTR14R =  62,	//< LT-rel. fct ptr, right 14 bits. 
+    R_PARISC_FPTR64 =         64,	//< 64 bits function address.  
+    R_PARISC_PLABEL32 =       65,	//< 32 bits function address.  
+    R_PARISC_PLABEL21L =      66,	//< Left 21 bits of fdesc address 
+    R_PARISC_PLABEL14R =      70,	//< Right 14 bits of fdesc address 
+    R_PARISC_PCREL64 =        72,	//< 64 bits PC-rel. address.  
+    R_PARISC_PCREL22F =       74,	//< 22 bits PC-rel. address.  
+    R_PARISC_PCREL14WR =      75,	//< PC-rel. address, right 14 bits.  
+    R_PARISC_PCREL14DR =      76,	//< PC rel. address, right 14 bits.  
+    R_PARISC_PCREL16F =       77,	//< 16 bits PC-rel. address.  
+    R_PARISC_PCREL16WF =      78,	//< 16 bits PC-rel. address.  
+    R_PARISC_PCREL16DF =      79,	//< 16 bits PC-rel. address.  
+    R_PARISC_DIR64 =          80,	//< 64 bits of eff. address.  
+    R_PARISC_DIR14WR =        83,	//< 14 bits of eff. address.  
+    R_PARISC_DIR14DR =        84,	//< 14 bits of eff. address.  
+    R_PARISC_DIR16F =         85,	//< 16 bits of eff. address.  
+    R_PARISC_DIR16WF =        86,	//< 16 bits of eff. address.  
+    R_PARISC_DIR16DF =        87,	//< 16 bits of eff. address.  
+    R_PARISC_GPREL64 =        88,	//< 64 bits of GP-rel. address.  
+    R_PARISC_GPREL14WR =      91,	//< GP-rel. address, right 14 bits.  
+    R_PARISC_GPREL14DR =      92,	//< GP-rel. address, right 14 bits.  
+    R_PARISC_GPREL16F =       93,	//< 16 bits GP-rel. address.  
+    R_PARISC_GPREL16WF =      94,	//< 16 bits GP-rel. address.  
+    R_PARISC_GPREL16DF =      95,	//< 16 bits GP-rel. address.  
+    R_PARISC_LTOFF64 =        96,	//< 64 bits LT-rel. address.  
+    R_PARISC_LTOFF14WR =      99,	//< LT-rel. address, right 14 bits.  
+    R_PARISC_LTOFF14DR =      100,	//< LT-rel. address, right 14 bits.  
+    R_PARISC_LTOFF16F =       101,	//< 16 bits LT-rel. address.  
+    R_PARISC_LTOFF16WF =      102,	//< 16 bits LT-rel. address.  
+    R_PARISC_LTOFF16DF =      103,	//< 16 bits LT-rel. address.  
+    R_PARISC_SECREL64 =       104,	//< 64 bits section rel. address.  
+    R_PARISC_SEGREL64 =       112,	//< 64 bits segment rel. address.  
+    R_PARISC_PLTOFF14WR =     115,	//< PLT-rel. address, right 14 bits.  
+    R_PARISC_PLTOFF14DR =     116,	//< PLT-rel. address, right 14 bits.  
+    R_PARISC_PLTOFF16F =      117,	//< 16 bits LT-rel. address.  
+    R_PARISC_PLTOFF16WF =     118,	//< 16 bits PLT-rel. address.  
+    R_PARISC_PLTOFF16DF =     119,	//< 16 bits PLT-rel. address.  
+    R_PARISC_LTOFF_FPTR64 =   120,	//< 64 bits LT-rel. function ptr.  
+    R_PARISC_LTOFF_FPTR14WR = 123,	//< LT-rel. fct. ptr., right 14 bits. 
+    R_PARISC_LTOFF_FPTR14DR = 124,	//< LT-rel. fct. ptr., right 14 bits. 
+    R_PARISC_LTOFF_FPTR16F =  125,	//< 16 bits LT-rel. function ptr.  
+    R_PARISC_LTOFF_FPTR16WF = 126,	//< 16 bits LT-rel. function ptr.  
+    R_PARISC_LTOFF_FPTR16DF = 127,	//< 16 bits LT-rel. function ptr.  
+    R_PARISC_LORESERVE =      128,
+    R_PARISC_COPY =           128,	//< Copy relocation.  
+    R_PARISC_IPLT =           129,	//< Dynamic reloc, imported PLT 
+    R_PARISC_EPLT =           130,	//< Dynamic reloc, exported PLT 
+    R_PARISC_TPREL32 =        153,	//< 32 bits TP-rel. address.  
+    R_PARISC_TPREL21L =       154,	//< TP-rel. address, left 21 bits.  
+    R_PARISC_TPREL14R =       158,	//< TP-rel. address, right 14 bits.  
+    R_PARISC_LTOFF_TP21L =    162,	//< LT-TP-rel. address, left 21 bits. 
+    R_PARISC_LTOFF_TP14R =    166,	//< LT-TP-rel. address, right 14 bits.
+    R_PARISC_LTOFF_TP14F =    167,	//< 14 bits LT-TP-rel. address.  
+    R_PARISC_TPREL64 =        216,	//< 64 bits TP-rel. address.  
+    R_PARISC_TPREL14WR =      219,	//< TP-rel. address, right 14 bits.  
+    R_PARISC_TPREL14DR =      220,	//< TP-rel. address, right 14 bits.  
+    R_PARISC_TPREL16F =       221,	//< 16 bits TP-rel. address.  
+    R_PARISC_TPREL16WF =      222,	//< 16 bits TP-rel. address.  
+    R_PARISC_TPREL16DF =      223,	//< 16 bits TP-rel. address.  
+    R_PARISC_LTOFF_TP64 =     224,	//< 64 bits LT-TP-rel. address.  
+    R_PARISC_LTOFF_TP14WR =   227,	//< LT-TP-rel. address, right 14 bits.
+    R_PARISC_LTOFF_TP14DR =   228,	//< LT-TP-rel. address, right 14 bits.
+    R_PARISC_LTOFF_TP16F =    229,	//< 16 bits LT-TP-rel. address.  
+    R_PARISC_LTOFF_TP16WF =   230,	//< 16 bits LT-TP-rel. address.  
+    R_PARISC_LTOFF_TP16DF =   231,	//< 16 bits LT-TP-rel. address.  
+    R_PARISC_GNU_VTENTRY =    232,
+    R_PARISC_GNU_VTINHERIT =  233,
+    R_PARISC_TLS_GD21L =      234,	//< GD 21-bit left 
+    R_PARISC_TLS_GD14R =      235,	//< GD 14-bit right 
+    R_PARISC_TLS_GDCALL =     236,	//< GD call to __t_g_a 
+    R_PARISC_TLS_LDM21L =     237,	//< LD module 21-bit left 
+    R_PARISC_TLS_LDM14R =     238,	//< LD module 14-bit right 
+    R_PARISC_TLS_LDMCALL =    239,	//< LD module call to __t_g_a 
+    R_PARISC_TLS_LDO21L =     240,	//< LD offset 21-bit left 
+    R_PARISC_TLS_LDO14R =     241,	//< LD offset 14-bit right 
+    R_PARISC_TLS_DTPMOD32 =   242,	//< DTP module 32-bit 
+    R_PARISC_TLS_DTPMOD64 =   243,	//< DTP module 64-bit 
+    R_PARISC_TLS_DTPOFF32 =   244,	//< DTP offset 32-bit 
+    R_PARISC_TLS_DTPOFF64 =   245,	//< DTP offset 32-bit 
+    R_PARISC_TLS_LE21L =      R_PARISC_TPREL21L,
+    R_PARISC_TLS_LE14R =      R_PARISC_TPREL14R,
+    R_PARISC_TLS_IE21L =      R_PARISC_LTOFF_TP21L,
+    R_PARISC_TLS_IE14R =      R_PARISC_LTOFF_TP14R,
+    R_PARISC_TLS_TPREL32 =    R_PARISC_TPREL32,
+    R_PARISC_TLS_TPREL64 =    R_PARISC_TPREL64,
+    R_PARISC_HIRESERVE =      255,
+
+    /* Alpha relocs.  */
+    R_ALPHA_NONE =            0,	//< No reloc 
+    R_ALPHA_REFLONG =         1,	//< Direct 32 bit 
+    R_ALPHA_REFQUAD =         2,	//< Direct 64 bit 
+    R_ALPHA_GPREL32 =         3,	//< GP relative 32 bit 
+    R_ALPHA_LITERAL =         4,	//< GP relative 16 bit w/optimization 
+    R_ALPHA_LITUSE =          5,	//< Optimization hint for LITERAL 
+    R_ALPHA_GPDISP =          6,	//< Add displacement to GP 
+    R_ALPHA_BRADDR =          7,	//< PC+4 relative 23 bit shifted 
+    R_ALPHA_HINT =            8,	//< PC+4 relative 16 bit shifted 
+    R_ALPHA_SREL16 =          9,	//< PC relative 16 bit 
+    R_ALPHA_SREL32 =          10,	//< PC relative 32 bit 
+    R_ALPHA_SREL64 =          11,	//< PC relative 64 bit 
+    R_ALPHA_GPRELHIGH =       17,	//< GP relative 32 bit, high 16 bits 
+    R_ALPHA_GPRELLOW =        18,	//< GP relative 32 bit, low 16 bits 
+    R_ALPHA_GPREL16 =         19,	//< GP relative 16 bit 
+    R_ALPHA_COPY =            24,	//< Copy symbol at runtime 
+    R_ALPHA_GLOB_DAT =        25,	//< Create GOT entry 
+    R_ALPHA_JMP_SLOT =        26,	//< Create PLT entry 
+    R_ALPHA_RELATIVE =        27,	//< Adjust by program base 
+    R_ALPHA_TLS_GD_HI =       28,
+    R_ALPHA_TLSGD =           29,
+    R_ALPHA_TLS_LDM =         30,
+    R_ALPHA_DTPMOD64 =        31,
+    R_ALPHA_GOTDTPREL =       32,
+    R_ALPHA_DTPREL64 =        33,
+    R_ALPHA_DTPRELHI =        34,
+    R_ALPHA_DTPRELLO =        35,
+    R_ALPHA_DTPREL16 =        36,
+    R_ALPHA_GOTTPREL =        37,
+    R_ALPHA_TPREL64 =         38,
+    R_ALPHA_TPRELHI =         39,
+    R_ALPHA_TPRELLO =         40,
+    R_ALPHA_TPREL16 =         41,
+    /* Keep this the last entry.  */
+    R_ALPHA_NUM =             46,
+
+/* PowerPC relocations defined by the ABIs */
+    R_PPC_NONE =              0,
+    R_PPC_ADDR32 =            1,	//< 32bit absolute address 
+    R_PPC_ADDR24 =            2,	//< 26bit address, 2 bits ignored.  
+    R_PPC_ADDR16 =            3,	//< 16bit absolute address 
+    R_PPC_ADDR16_LO =         4,	//< lower 16bit of absolute address 
+    R_PPC_ADDR16_HI =         5,	//< high 16bit of absolute address 
+    R_PPC_ADDR16_HA =         6,	//< adjusted high 16bit 
+    R_PPC_ADDR14 =            7,	//< 16bit address, 2 bits ignored 
+    R_PPC_ADDR14_BRTAKEN =    8,
+    R_PPC_ADDR14_BRNTAKEN =   9,
+    R_PPC_REL24 =             10,	//< PC relative 26 bit 
+    R_PPC_REL14 =             11,	//< PC relative 16 bit 
+    R_PPC_REL14_BRTAKEN =     12,
+    R_PPC_REL14_BRNTAKEN =    13,
+    R_PPC_GOT16 =             14,
+    R_PPC_GOT16_LO =          15,
+    R_PPC_GOT16_HI =          16,
+    R_PPC_GOT16_HA =          17,
+    R_PPC_PLTREL24 =          18,
+    R_PPC_COPY =              19,
+    R_PPC_GLOB_DAT =          20,
+    R_PPC_JMP_SLOT =          21,
+    R_PPC_RELATIVE =          22,
+    R_PPC_LOCAL24PC =         23,
+    R_PPC_UADDR32 =           24,
+    R_PPC_UADDR16 =           25,
+    R_PPC_REL32 =             26,
+    R_PPC_PLT32 =             27,
+    R_PPC_PLTREL32 =          28,
+    R_PPC_PLT16_LO =          29,
+    R_PPC_PLT16_HI =          30,
+    R_PPC_PLT16_HA =          31,
+    R_PPC_SDAREL16 =          32,
+    R_PPC_SECTOFF =           33,
+    R_PPC_SECTOFF_LO =        34,
+    R_PPC_SECTOFF_HI =        35,
+    R_PPC_SECTOFF_HA =        36,
+
+/* PowerPC relocations defined for the TLS access ABI.  */
+    R_PPC_TLS =               67,	//< none      (sym+add)@@tls 
+    R_PPC_DTPMOD32 =          68,	//< word32    (sym+add)@@dtpmod 
+    R_PPC_TPREL16 =           69,	//< half16*   (sym+add)@@tprel 
+    R_PPC_TPREL16_LO =        70,	//< half16    (sym+add)@@tprel@@l 
+    R_PPC_TPREL16_HI =        71,	//< half16    (sym+add)@@tprel@@h 
+    R_PPC_TPREL16_HA =        72,	//< half16    (sym+add)@@tprel@@ha 
+    R_PPC_TPREL32 =           73,	//< word32    (sym+add)@@tprel 
+    R_PPC_DTPREL16 =          74,	//< half16*   (sym+add)@@dtprel 
+    R_PPC_DTPREL16_LO =       75,	//< half16    (sym+add)@@dtprel@@l 
+    R_PPC_DTPREL16_HI =       76,	//< half16    (sym+add)@@dtprel@@h 
+    R_PPC_DTPREL16_HA =       77,	//< half16    (sym+add)@@dtprel@@ha 
+    R_PPC_DTPREL32 =          78,	//< word32    (sym+add)@@dtprel 
+    R_PPC_GOT_TLSGD16 =       79,	//< half16*   (sym+add)@@got@@tlsgd 
+    R_PPC_GOT_TLSGD16_LO =    80,	//< half16    (sym+add)@@got@@tlsgd@@l 
+    R_PPC_GOT_TLSGD16_HI =    81,	//< half16    (sym+add)@@got@@tlsgd@@h 
+    R_PPC_GOT_TLSGD16_HA =    82,	//< half16    (sym+add)@@got@@tlsgd@@ha 
+    R_PPC_GOT_TLSLD16 =       83,	//< half16*   (sym+add)@@got@@tlsld 
+    R_PPC_GOT_TLSLD16_LO =    84,	//< half16    (sym+add)@@got@@tlsld@@l 
+    R_PPC_GOT_TLSLD16_HI =    85,	//< half16    (sym+add)@@got@@tlsld@@h 
+    R_PPC_GOT_TLSLD16_HA =    86,	//< half16    (sym+add)@@got@@tlsld@@ha 
+    R_PPC_GOT_TPREL16 =       87,	//< half16*   (sym+add)@@got@@tprel 
+    R_PPC_GOT_TPREL16_LO =    88,	//< half16    (sym+add)@@got@@tprel@@l 
+    R_PPC_GOT_TPREL16_HI =    89,	//< half16    (sym+add)@@got@@tprel@@h 
+    R_PPC_GOT_TPREL16_HA =    90,	//< half16    (sym+add)@@got@@tprel@@ha 
+    R_PPC_GOT_DTPREL16 =      91,	//< half16*   (sym+add)@@got@@dtprel 
+    R_PPC_GOT_DTPREL16_LO =   92,	//< half16*   (sym+add)@@got@@dtprel@@l 
+    R_PPC_GOT_DTPREL16_HI =   93,	//< half16*   (sym+add)@@got@@dtprel@@h 
+    R_PPC_GOT_DTPREL16_HA =   94,	//< half16*   (sym+add)@@got@@dtprel@@ha 
+
+/* Keep this the last entry.  */
+    R_PPC_NUM =               95,
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+    R_PPC_EMB_NADDR32 =       101,
+    R_PPC_EMB_NADDR16 =       102,
+    R_PPC_EMB_NADDR16_LO =    103,
+    R_PPC_EMB_NADDR16_HI =    104,
+    R_PPC_EMB_NADDR16_HA =    105,
+    R_PPC_EMB_SDAI16 =        106,
+    R_PPC_EMB_SDA2I16 =       107,
+    R_PPC_EMB_SDA2REL =       108,
+    R_PPC_EMB_SDA21 =         109,	//< 16 bit offset in SDA 
+    R_PPC_EMB_MRKREF =        110,
+    R_PPC_EMB_RELSEC16 =      111,
+    R_PPC_EMB_RELST_LO =      112,
+    R_PPC_EMB_RELST_HI =      113,
+    R_PPC_EMB_RELST_HA =      114,
+    R_PPC_EMB_BIT_FLD =       115,
+    R_PPC_EMB_RELSDA =        116,	//< 16 bit relative offset in SDA 
+
+/* Diab tool relocations.  */
+    R_PPC_DIAB_SDA21_LO =     180,	//< like EMB_SDA21, but lower 16 bit 
+    R_PPC_DIAB_SDA21_HI =     181,	//< like EMB_SDA21, but high 16 bit 
+    R_PPC_DIAB_SDA21_HA =     182,	//< like EMB_SDA21, adjusted high 16 
+    R_PPC_DIAB_RELSDA_LO =    183,	//< like EMB_RELSDA, but lower 16 bit 
+    R_PPC_DIAB_RELSDA_HI =    184,	//< like EMB_RELSDA, but high 16 bit 
+    R_PPC_DIAB_RELSDA_HA =    185,	//< like EMB_RELSDA, adjusted high 16 
+
+/* GNU relocs used in PIC code sequences.  */
+    R_PPC_REL16 =             249,	//< word32   (sym-.) 
+    R_PPC_REL16_LO =          250,	//< half16   (sym-.)@@l 
+    R_PPC_REL16_HI =          251,	//< half16   (sym-.)@@h 
+    R_PPC_REL16_HA =          252,	//< half16   (sym-.)@@ha 
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+    R_PPC_TOC16 =             255,
+
+/* PowerPC64 relocations defined by the ABIs */
+    R_PPC64_NONE =            R_PPC_NONE,
+    R_PPC64_ADDR32 =          R_PPC_ADDR32,	//< 32bit absolute address 
+    R_PPC64_ADDR24 =          R_PPC_ADDR24,	//< 26bit address, word aligned 
+    R_PPC64_ADDR16 =          R_PPC_ADDR16,	//< 16bit absolute address 
+    R_PPC64_ADDR16_LO =       R_PPC_ADDR16_LO,	//< lower 16bits of address 
+    R_PPC64_ADDR16_HI =       R_PPC_ADDR16_HI,	//< high 16bits of address. 
+    R_PPC64_ADDR16_HA =       R_PPC_ADDR16_HA,	//< adjusted high 16bits.  
+    R_PPC64_ADDR14 =          R_PPC_ADDR14,	//< 16bit address, word aligned 
+    R_PPC64_ADDR14_BRTAKEN =  R_PPC_ADDR14_BRTAKEN,
+    R_PPC64_ADDR14_BRNTAKEN = R_PPC_ADDR14_BRNTAKEN,
+    R_PPC64_REL24 =           R_PPC_REL24,	//< PC-rel. 26 bit, word aligned 
+    R_PPC64_REL14 =           R_PPC_REL14,	//< PC relative 16 bit 
+    R_PPC64_REL14_BRTAKEN =   R_PPC_REL14_BRTAKEN,
+    R_PPC64_REL14_BRNTAKEN =  R_PPC_REL14_BRNTAKEN,
+    R_PPC64_GOT16 =           R_PPC_GOT16,
+    R_PPC64_GOT16_LO =        R_PPC_GOT16_LO,
+    R_PPC64_GOT16_HI =        R_PPC_GOT16_HI,
+    R_PPC64_GOT16_HA =        R_PPC_GOT16_HA,
+    R_PPC64_COPY =            R_PPC_COPY,
+    R_PPC64_GLOB_DAT =        R_PPC_GLOB_DAT,
+    R_PPC64_JMP_SLOT =        R_PPC_JMP_SLOT,
+    R_PPC64_RELATIVE =        R_PPC_RELATIVE,
+    R_PPC64_UADDR32 =         R_PPC_UADDR32,
+    R_PPC64_UADDR16 =         R_PPC_UADDR16,
+    R_PPC64_REL32 =           R_PPC_REL32,
+    R_PPC64_PLT32 =           R_PPC_PLT32,
+    R_PPC64_PLTREL32 =        R_PPC_PLTREL32,
+    R_PPC64_PLT16_LO =        R_PPC_PLT16_LO,
+    R_PPC64_PLT16_HI =        R_PPC_PLT16_HI,
+    R_PPC64_PLT16_HA =        R_PPC_PLT16_HA,
+    R_PPC64_SECTOFF =         R_PPC_SECTOFF,
+    R_PPC64_SECTOFF_LO =      R_PPC_SECTOFF_LO,
+    R_PPC64_SECTOFF_HI =      R_PPC_SECTOFF_HI,
+    R_PPC64_SECTOFF_HA =      R_PPC_SECTOFF_HA,
+    R_PPC64_ADDR30 =          37,	//< word30 (S + A - P) >> 2 
+    R_PPC64_ADDR64 =          38,	//< doubleword64 S + A 
+    R_PPC64_ADDR16_HIGHER =   39,	//< half16 #higher(S + A) 
+    R_PPC64_ADDR16_HIGHERA =  40,	//< half16 #highera(S + A) 
+    R_PPC64_ADDR16_HIGHEST =  41,	//< half16 #highest(S + A) 
+    R_PPC64_ADDR16_HIGHESTA = 42,	//< half16 #highesta(S + A) 
+    R_PPC64_UADDR64 =         43,	//< doubleword64 S + A 
+    R_PPC64_REL64 =           44,	//< doubleword64 S + A - P 
+    R_PPC64_PLT64 =           45,	//< doubleword64 L + A 
+    R_PPC64_PLTREL64 =        46,	//< doubleword64 L + A - P 
+    R_PPC64_TOC16 =           47,	//< half16* S + A - .TOC 
+    R_PPC64_TOC16_LO =        48,	//< half16 #lo(S + A - .TOC.) 
+    R_PPC64_TOC16_HI =        49,	//< half16 #hi(S + A - .TOC.) 
+    R_PPC64_TOC16_HA =        50,	//< half16 #ha(S + A - .TOC.) 
+    R_PPC64_TOC =             51,	//< doubleword64 .TOC 
+    R_PPC64_PLTGOT16 =        52,	//< half16* M + A 
+    R_PPC64_PLTGOT16_LO =     53,	//< half16 #lo(M + A) 
+    R_PPC64_PLTGOT16_HI =     54,	//< half16 #hi(M + A) 
+    R_PPC64_PLTGOT16_HA =     55,	//< half16 #ha(M + A) 
+    R_PPC64_ADDR16_DS =       56,	//< half16ds* (S + A) >> 2 
+    R_PPC64_ADDR16_LO_DS =    57,	//< half16ds  #lo(S + A) >> 2 
+    R_PPC64_GOT16_DS =        58,	//< half16ds* (G + A) >> 2 
+    R_PPC64_GOT16_LO_DS =     59,	//< half16ds  #lo(G + A) >> 2 
+    R_PPC64_PLT16_LO_DS =     60,	//< half16ds  #lo(L + A) >> 2 
+    R_PPC64_SECTOFF_DS =      61,	//< half16ds* (R + A) >> 2 
+    R_PPC64_SECTOFF_LO_DS =   62,	//< half16ds  #lo(R + A) >> 2 
+    R_PPC64_TOC16_DS =        63,	//< half16ds* (S + A - .TOC.) >> 2 
+    R_PPC64_TOC16_LO_DS =     64,	//< half16ds  #lo(S + A - .TOC.) >> 2 
+    R_PPC64_PLTGOT16_DS =     65,	//< half16ds* (M + A) >> 2 
+    R_PPC64_PLTGOT16_LO_DS =  66,	//< half16ds  #lo(M + A) >> 2 
+    /* PowerPC64 relocations defined for the TLS access ABI.  */
+    R_PPC64_TLS =             67,	//< none      (sym+add)@@tls 
+    R_PPC64_DTPMOD64 =        68,	//< doubleword64 (sym+add)@@dtpmod 
+    R_PPC64_TPREL16 =         69,	//< half16*   (sym+add)@@tprel 
+    R_PPC64_TPREL16_LO =      70,	//< half16    (sym+add)@@tprel@@l 
+    R_PPC64_TPREL16_HI =      71,	//< half16    (sym+add)@@tprel@@h 
+    R_PPC64_TPREL16_HA =      72,	//< half16    (sym+add)@@tprel@@ha 
+    R_PPC64_TPREL64 =         73,	//< doubleword64 (sym+add)@@tprel 
+    R_PPC64_DTPREL16 =        74,	//< half16*   (sym+add)@@dtprel 
+    R_PPC64_DTPREL16_LO =     75,	//< half16    (sym+add)@@dtprel@@l 
+    R_PPC64_DTPREL16_HI =     76,	//< half16    (sym+add)@@dtprel@@h 
+    R_PPC64_DTPREL16_HA =     77,	//< half16    (sym+add)@@dtprel@@ha 
+    R_PPC64_DTPREL64 =        78,	//< doubleword64 (sym+add)@@dtprel 
+    R_PPC64_GOT_TLSGD16 =     79,	//< half16*   (sym+add)@@got@@tlsgd 
+    R_PPC64_GOT_TLSGD16_LO =  80,	//< half16    (sym+add)@@got@@tlsgd@@l 
+    R_PPC64_GOT_TLSGD16_HI =  81,	//< half16    (sym+add)@@got@@tlsgd@@h 
+    R_PPC64_GOT_TLSGD16_HA =  82,	//< half16    (sym+add)@@got@@tlsgd@@ha 
+    R_PPC64_GOT_TLSLD16 =     83,	//< half16*   (sym+add)@@got@@tlsld 
+    R_PPC64_GOT_TLSLD16_LO =  84,	//< half16    (sym+add)@@got@@tlsld@@l 
+    R_PPC64_GOT_TLSLD16_HI =  85,	//< half16    (sym+add)@@got@@tlsld@@h 
+    R_PPC64_GOT_TLSLD16_HA =  86,	//< half16    (sym+add)@@got@@tlsld@@ha 
+    R_PPC64_GOT_TPREL16_DS =  87,	//< half16ds* (sym+add)@@got@@tprel 
+    R_PPC64_GOT_TPREL16_LO_DS = 88,	//< half16ds (sym+add)@@got@@tprel@@l 
+    R_PPC64_GOT_TPREL16_HI =  89,	//< half16    (sym+add)@@got@@tprel@@h 
+    R_PPC64_GOT_TPREL16_HA =  90,	//< half16    (sym+add)@@got@@tprel@@ha 
+    R_PPC64_GOT_DTPREL16_DS = 91,	//< half16ds* (sym+add)@@got@@dtprel 
+    R_PPC64_GOT_DTPREL16_LO_DS = 92,	//< half16ds (sym+add)@@got@@dtprel@@l 
+    R_PPC64_GOT_DTPREL16_HI = 93,	//< half16    (sym+add)@@got@@dtprel@@h 
+    R_PPC64_GOT_DTPREL16_HA = 94,	//< half16    (sym+add)@@got@@dtprel@@ha 
+    R_PPC64_TPREL16_DS =      95,	//< half16ds* (sym+add)@@tprel 
+    R_PPC64_TPREL16_LO_DS =   96,	//< half16ds  (sym+add)@@tprel@@l 
+    R_PPC64_TPREL16_HIGHER =  97,	//< half16    (sym+add)@@tprel@@higher 
+    R_PPC64_TPREL16_HIGHERA = 98,	//< half16    (sym+add)@@tprel@@highera 
+    R_PPC64_TPREL16_HIGHEST = 99,	//< half16    (sym+add)@@tprel@@highest 
+    R_PPC64_TPREL16_HIGHESTA = 100,	//< half16  (sym+add)@@tprel@@highesta 
+    R_PPC64_DTPREL16_DS =     101,	//< half16ds* (sym+add)@@dtprel 
+    R_PPC64_DTPREL16_LO_DS =  102,	//< half16ds (sym+add)@@dtprel@@l 
+    R_PPC64_DTPREL16_HIGHER = 103,	//< half16   (sym+add)@@dtprel@@higher 
+    R_PPC64_DTPREL16_HIGHERA = 104,	//< half16  (sym+add)@@dtprel@@highera 
+    R_PPC64_DTPREL16_HIGHEST = 105,	//< half16  (sym+add)@@dtprel@@highest 
+    R_PPC64_DTPREL16_HIGHESTA = 106,	//< half16 (sym+add)@@dtprel@@highesta 
+
+    /* Keep this the last entry.  */
+    R_PPC64_NUM =             107,
+
+    /* ARM relocs.  */
+    R_ARM_NONE =              0,	//< No reloc 
+    R_ARM_PC24 =              1,	//< PC relative 26 bit branch 
+    R_ARM_ABS32 =             2,	//< Direct 32 bit  
+    R_ARM_REL32 =             3,	//< PC relative 32 bit 
+    R_ARM_PC13 =              4,
+    R_ARM_ABS16 =             5,	//< Direct 16 bit 
+    R_ARM_ABS12 =             6,	//< Direct 12 bit 
+    R_ARM_THM_ABS5 =          7,
+    R_ARM_ABS8 =              8,	//< Direct 8 bit 
+    R_ARM_SBREL32 =           9,
+    R_ARM_THM_PC22 =          10,
+    R_ARM_THM_PC8 =           11,
+    R_ARM_AMP_VCALL9 =        12,
+    R_ARM_SWI24 =             13,
+    R_ARM_THM_SWI8 =          14,
+    R_ARM_XPC25 =             15,
+    R_ARM_THM_XPC22 =         16,
+    R_ARM_TLS_DTPMOD32 =      17,	//< ID of module containing symbol 
+    R_ARM_TLS_DTPOFF32 =      18,	//< Offset in TLS block 
+    R_ARM_TLS_TPOFF32 =       19,	//< Offset in static TLS block 
+    R_ARM_COPY =              20,	//< Copy symbol at runtime 
+    R_ARM_GLOB_DAT =          21,	//< Create GOT entry 
+    R_ARM_JUMP_SLOT =         22,	//< Create PLT entry 
+    R_ARM_RELATIVE =          23,	//< Adjust by program base 
+    R_ARM_GOTOFF =            24,	//< 32 bit offset to GOT 
+    R_ARM_GOTPC =             25,	//< 32 bit PC relative offset to GOT 
+    R_ARM_GOT32 =             26,	//< 32 bit GOT entry 
+    R_ARM_PLT32 =             27,	//< 32 bit PLT address 
+    R_ARM_ALU_PCREL_7_0 =     32,
+    R_ARM_ALU_PCREL_15_8 =    33,
+    R_ARM_ALU_PCREL_23_15 =   34,
+    R_ARM_LDR_SBREL_11_0 =    35,
+    R_ARM_ALU_SBREL_19_12 =   36,
+    R_ARM_ALU_SBREL_27_20 =   37,
+    R_ARM_GNU_VTENTRY =       100,
+    R_ARM_GNU_VTINHERIT =     101,
+    R_ARM_THM_PC11 =          102,	//< thumb unconditional branch 
+    R_ARM_THM_PC9 =           103,	//< thumb conditional branch 
+    R_ARM_TLS_GD32 =          104,	//< PC-rel 32 bit for global dynamic thread local data 
+    R_ARM_TLS_LDM32 =         105,	//< PC-rel 32 bit for local dynamic thread local data 
+    R_ARM_TLS_LDO32 =         106,	//< 32 bit offset relative to TLS block 
+    R_ARM_TLS_IE32 =          107,	//< PC-rel 32 bit for GOT entry of static TLS block offset 
+    R_ARM_TLS_LE32 =          108,	//< 32 bit offset relative to static TLS block 
+    R_ARM_RXPC25 =            249,
+    R_ARM_RSBREL32 =          250,
+    R_ARM_THM_RPC22 =         251,
+    R_ARM_RREL32 =            252,
+    R_ARM_RABS22 =            253,
+    R_ARM_RPC24 =             254,
+    R_ARM_RBASE =             255,
+    /* Keep this the last entry.  */
+    R_ARM_NUM =               256,
+
+/* IA-64 relocations.  */
+    R_IA64_NONE =             0x00,	//< none 
+    R_IA64_IMM14 =            0x21,	//< symbol + addend, add imm14 
+    R_IA64_IMM22 =            0x22,	//< symbol + addend, add imm22 
+    R_IA64_IMM64 =            0x23,	//< symbol + addend, mov imm64 
+    R_IA64_DIR32MSB =         0x24,	//< symbol + addend, data4 MSB 
+    R_IA64_DIR32LSB =         0x25,	//< symbol + addend, data4 LSB 
+    R_IA64_DIR64MSB =         0x26,	//< symbol + addend, data8 MSB 
+    R_IA64_DIR64LSB =         0x27,	//< symbol + addend, data8 LSB 
+    R_IA64_GPREL22 =          0x2a,	//< @@gprel(sym + add), add imm22 
+    R_IA64_GPREL64I =         0x2b,	//< @@gprel(sym + add), mov imm64 
+    R_IA64_GPREL32MSB =       0x2c,	//< @@gprel(sym + add), data4 MSB 
+    R_IA64_GPREL32LSB =       0x2d,	//< @@gprel(sym + add), data4 LSB 
+    R_IA64_GPREL64MSB =       0x2e,	//< @@gprel(sym + add), data8 MSB 
+    R_IA64_GPREL64LSB =       0x2f,	//< @@gprel(sym + add), data8 LSB 
+    R_IA64_LTOFF22 =          0x32,	//< @@ltoff(sym + add), add imm22 
+    R_IA64_LTOFF64I =         0x33,	//< @@ltoff(sym + add), mov imm64 
+    R_IA64_PLTOFF22 =         0x3a,	//< @@pltoff(sym + add), add imm22 
+    R_IA64_PLTOFF64I =        0x3b,	//< @@pltoff(sym + add), mov imm64 
+    R_IA64_PLTOFF64MSB =      0x3e,	//< @@pltoff(sym + add), data8 MSB 
+    R_IA64_PLTOFF64LSB =      0x3f,	//< @@pltoff(sym + add), data8 LSB 
+    R_IA64_FPTR64I =          0x43,	//< @@fptr(sym + add), mov imm64 
+    R_IA64_FPTR32MSB =        0x44,	//< @@fptr(sym + add), data4 MSB 
+    R_IA64_FPTR32LSB =        0x45,	//< @@fptr(sym + add), data4 LSB 
+    R_IA64_FPTR64MSB =        0x46,	//< @@fptr(sym + add), data8 MSB 
+    R_IA64_FPTR64LSB =        0x47,	//< @@fptr(sym + add), data8 LSB 
+    R_IA64_PCREL60B =         0x48,	//< @@pcrel(sym + add), brl 
+    R_IA64_PCREL21B =         0x49,	//< @@pcrel(sym + add), ptb, call 
+    R_IA64_PCREL21M =         0x4a,	//< @@pcrel(sym + add), chk.s 
+    R_IA64_PCREL21F =         0x4b,	//< @@pcrel(sym + add), fchkf 
+    R_IA64_PCREL32MSB =       0x4c,	//< @@pcrel(sym + add), data4 MSB 
+    R_IA64_PCREL32LSB =       0x4d,	//< @@pcrel(sym + add), data4 LSB 
+    R_IA64_PCREL64MSB =       0x4e,	//< @@pcrel(sym + add), data8 MSB 
+    R_IA64_PCREL64LSB =       0x4f,	//< @@pcrel(sym + add), data8 LSB 
+    R_IA64_LTOFF_FPTR22 =     0x52,	//< @@ltoff(@@fptr(s+a)), imm22 
+    R_IA64_LTOFF_FPTR64I =    0x53,	//< @@ltoff(@@fptr(s+a)), imm64 
+    R_IA64_LTOFF_FPTR32MSB =  0x54,	//< @@ltoff(@@fptr(s+a)), data4 MSB 
+    R_IA64_LTOFF_FPTR32LSB =  0x55,	//< @@ltoff(@@fptr(s+a)), data4 LSB 
+    R_IA64_LTOFF_FPTR64MSB =  0x56,	//< @@ltoff(@@fptr(s+a)), data8 MSB 
+    R_IA64_LTOFF_FPTR64LSB =  0x57,	//< @@ltoff(@@fptr(s+a)), data8 LSB 
+    R_IA64_SEGREL32MSB =      0x5c,	//< @@segrel(sym + add), data4 MSB 
+    R_IA64_SEGREL32LSB =      0x5d,	//< @@segrel(sym + add), data4 LSB 
+    R_IA64_SEGREL64MSB =      0x5e,	//< @@segrel(sym + add), data8 MSB 
+    R_IA64_SEGREL64LSB =      0x5f,	//< @@segrel(sym + add), data8 LSB 
+    R_IA64_SECREL32MSB =      0x64,	//< @@secrel(sym + add), data4 MSB 
+    R_IA64_SECREL32LSB =      0x65,	//< @@secrel(sym + add), data4 LSB 
+    R_IA64_SECREL64MSB =      0x66,	//< @@secrel(sym + add), data8 MSB 
+    R_IA64_SECREL64LSB =      0x67,	//< @@secrel(sym + add), data8 LSB 
+    R_IA64_REL32MSB =         0x6c,	//< data 4 + REL 
+    R_IA64_REL32LSB =         0x6d,	//< data 4 + REL 
+    R_IA64_REL64MSB =         0x6e,	//< data 8 + REL 
+    R_IA64_REL64LSB =         0x6f,	//< data 8 + REL 
+    R_IA64_LTV32MSB =         0x74,	//< symbol + addend, data4 MSB 
+    R_IA64_LTV32LSB =         0x75,	//< symbol + addend, data4 LSB 
+    R_IA64_LTV64MSB =         0x76,	//< symbol + addend, data8 MSB 
+    R_IA64_LTV64LSB =         0x77,	//< symbol + addend, data8 LSB 
+    R_IA64_PCREL21BI =        0x79,	//< @@pcrel(sym + add), 21bit inst 
+    R_IA64_PCREL22 =          0x7a,	//< @@pcrel(sym + add), 22bit inst 
+    R_IA64_PCREL64I =         0x7b,	//< @@pcrel(sym + add), 64bit inst 
+    R_IA64_IPLTMSB =          0x80,	//< dynamic reloc, imported PLT, MSB 
+    R_IA64_IPLTLSB =          0x81,	//< dynamic reloc, imported PLT, LSB 
+    R_IA64_COPY =             0x84,	//< copy relocation 
+    R_IA64_SUB =              0x85,	//< Addend and symbol difference 
+    R_IA64_LTOFF22X =         0x86,	//< LTOFF22, relaxable.  
+    R_IA64_LDXMOV =           0x87,	//< Use of LTOFF22X.  
+    R_IA64_TPREL14 =          0x91,	//< @@tprel(sym + add), imm14 
+    R_IA64_TPREL22 =          0x92,	//< @@tprel(sym + add), imm22 
+    R_IA64_TPREL64I =         0x93,	//< @@tprel(sym + add), imm64 
+    R_IA64_TPREL64MSB =       0x96,	//< @@tprel(sym + add), data8 MSB 
+    R_IA64_TPREL64LSB =       0x97,	//< @@tprel(sym + add), data8 LSB 
+    R_IA64_LTOFF_TPREL22 =    0x9a,	//< @@ltoff(@@tprel(s+a)), imm2 
+    R_IA64_DTPMOD64MSB =      0xa6,	//< @@dtpmod(sym + add), data8 MSB 
+    R_IA64_DTPMOD64LSB =      0xa7,	//< @@dtpmod(sym + add), data8 LSB 
+    R_IA64_LTOFF_DTPMOD22 =   0xaa,	//< @@ltoff(@@dtpmod(sym + add)), imm22 
+    R_IA64_DTPREL14 =         0xb1,	//< @@dtprel(sym + add), imm14 
+    R_IA64_DTPREL22 =         0xb2,	//< @@dtprel(sym + add), imm22 
+    R_IA64_DTPREL64I =        0xb3,	//< @@dtprel(sym + add), imm64 
+    R_IA64_DTPREL32MSB =      0xb4,	//< @@dtprel(sym + add), data4 MSB 
+    R_IA64_DTPREL32LSB =      0xb5,	//< @@dtprel(sym + add), data4 LSB 
+    R_IA64_DTPREL64MSB =      0xb6,	//< @@dtprel(sym + add), data8 MSB 
+    R_IA64_DTPREL64LSB =      0xb7,	//< @@dtprel(sym + add), data8 LSB 
+    R_IA64_LTOFF_DTPREL22 =   0xba,	//< @@ltoff(@@dtprel(s+a)), imm22 
+
+    /* SH relocs.  */
+    R_SH_NONE =               0,
+    R_SH_DIR32 =              1,
+    R_SH_REL32 =              2,
+    R_SH_DIR8WPN =            3,
+    R_SH_IND12W =             4,
+    R_SH_DIR8WPL =            5,
+    R_SH_DIR8WPZ =            6,
+    R_SH_DIR8BP =             7,
+    R_SH_DIR8W =              8,
+    R_SH_DIR8L =              9,
+    R_SH_SWITCH16 =           25,
+    R_SH_SWITCH32 =           26,
+    R_SH_USES =               27,
+    R_SH_COUNT =              28,
+    R_SH_ALIGN =              29,
+    R_SH_CODE =               30,
+    R_SH_DATA =               31,
+    R_SH_LABEL =              32,
+    R_SH_SWITCH8 =            33,
+    R_SH_GNU_VTINHERIT =      34,
+    R_SH_GNU_VTENTRY =        35,
+    R_SH_TLS_GD_32 =          144,
+    R_SH_TLS_LD_32 =          145,
+    R_SH_TLS_LDO_32 =         146,
+    R_SH_TLS_IE_32 =          147,
+    R_SH_TLS_LE_32 =          148,
+    R_SH_TLS_DTPMOD32 =       149,
+    R_SH_TLS_DTPOFF32 =       150,
+    R_SH_TLS_TPOFF32 =        151,
+    R_SH_GOT32 =              160,
+    R_SH_PLT32 =              161,
+    R_SH_COPY =               162,
+    R_SH_GLOB_DAT =           163,
+    R_SH_JMP_SLOT =           164,
+    R_SH_RELATIVE =           165,
+    R_SH_GOTOFF =             166,
+    R_SH_GOTPC =              167,
+    /* Keep this the last entry.  */
+    R_SH_NUM =                256,
+
+/* Additional s390 relocs */
+    R_390_NONE =              0,	//< No reloc.  
+    R_390_8 =                 1,	//< Direct 8 bit.  
+    R_390_12 =                2,	//< Direct 12 bit.  
+    R_390_16 =                3,	//< Direct 16 bit.  
+    R_390_32 =                4,	//< Direct 32 bit.  
+    R_390_PC32 =              5,	//< PC relative 32 bit.  
+    R_390_GOT12 =             6,	//< 12 bit GOT offset.  
+    R_390_GOT32 =             7,	//< 32 bit GOT offset.  
+    R_390_PLT32 =             8,	//< 32 bit PC relative PLT address.  
+    R_390_COPY =              9,	//< Copy symbol at runtime.  
+    R_390_GLOB_DAT =          10,	//< Create GOT entry.  
+    R_390_JMP_SLOT =          11,	//< Create PLT entry.  
+    R_390_RELATIVE =          12,	//< Adjust by program base.  
+    R_390_GOTOFF32 =          13,	//< 32 bit offset to GOT.         
+    R_390_GOTPC =             14,	//< 32 bit PC relative offset to GOT.  
+    R_390_GOT16 =             15,	//< 16 bit GOT offset.  
+    R_390_PC16 =              16,	//< PC relative 16 bit.  
+    R_390_PC16DBL =           17,	//< PC relative 16 bit shifted by 1.  
+    R_390_PLT16DBL =          18,	//< 16 bit PC rel. PLT shifted by 1.  
+    R_390_PC32DBL =           19,	//< PC relative 32 bit shifted by 1.  
+    R_390_PLT32DBL =          20,	//< 32 bit PC rel. PLT shifted by 1.  
+    R_390_GOTPCDBL =          21,	//< 32 bit PC rel. GOT shifted by 1.  
+    R_390_64 =                22,	//< Direct 64 bit.  
+    R_390_PC64 =              23,	//< PC relative 64 bit.  
+    R_390_GOT64 =             24,	//< 64 bit GOT offset.  
+    R_390_PLT64 =             25,	//< 64 bit PC relative PLT address.  
+    R_390_GOTENT =            26,	//< 32 bit PC rel. to GOT entry >> 1. 
+    R_390_GOTOFF16 =          27,	//< 16 bit offset to GOT. 
+    R_390_GOTOFF64 =          28,	//< 64 bit offset to GOT. 
+    R_390_GOTPLT12 =          29,	//< 12 bit offset to jump slot.  
+    R_390_GOTPLT16 =          30,	//< 16 bit offset to jump slot.  
+    R_390_GOTPLT32 =          31,	//< 32 bit offset to jump slot.  
+    R_390_GOTPLT64 =          32,	//< 64 bit offset to jump slot.  
+    R_390_GOTPLTENT =         33,	//< 32 bit rel. offset to jump slot.  
+    R_390_PLTOFF16 =          34,	//< 16 bit offset from GOT to PLT. 
+    R_390_PLTOFF32 =          35,	//< 32 bit offset from GOT to PLT. 
+    R_390_PLTOFF64 =          36,	//< 16 bit offset from GOT to PLT. 
+    R_390_TLS_LOAD =          37,	//< Tag for load insn in TLS code.  
+    R_390_TLS_GDCALL =        38,	//< Tag for function call in general dynamic TLS code. 
+    R_390_TLS_LDCALL =        39,	//< Tag for function call in local dynamic TLS code. 
+    R_390_TLS_GD32 =          40,	//< Direct 32 bit for general dynamic  thread local data.  
+    R_390_TLS_GD64 =          41,	//< Direct 64 bit for general dynamic thread local data.  
+    R_390_TLS_GOTIE12 =       42,	//< 12 bit GOT offset for static TLS  block offset.  
+    R_390_TLS_GOTIE32 =       43,	//< 32 bit GOT offset for static TLS  block offset.  
+    R_390_TLS_GOTIE64 =       44,	//< 64 bit GOT offset for static TLS   block offset. 
+    R_390_TLS_LDM32 =         45,	//< Direct 32 bit for local dynamic   thread local data in LE code.  
+    R_390_TLS_LDM64 =         46,	//< Direct 64 bit for local dynamic   thread local data in LE code.  
+    R_390_TLS_IE32 =          47,	//< 32 bit address of GOT entry for   negated static TLS block offset.  
+    R_390_TLS_IE64 =          48,	//< 64 bit address of GOT entry for   negated static TLS block offset.  
+    R_390_TLS_IEENT =         49,	//< 32 bit rel. offset to GOT entry for negated static TLS block offset.  
+    R_390_TLS_LE32 =          50,	//< 32 bit negated offset relative to static TLS block.  
+    R_390_TLS_LE64 =          51,	//< 64 bit negated offset relative to static TLS block.  
+    R_390_TLS_LDO32 =         52,	//< 32 bit offset relative to TLS block.  
+    R_390_TLS_LDO64 =         53,	//< 64 bit offset relative to TLS block.  
+    R_390_TLS_DTPMOD =        54,	//< ID of module containing symbol.  
+    R_390_TLS_DTPOFF =        55,	//< Offset in TLS block.  
+    R_390_TLS_TPOFF =         56,	//< Negated offset in static TLS  block.  
+    R_390_20 =                57,	//< Direct 20 bit.  
+    R_390_GOT20 =             58,	//< 20 bit GOT offset.  
+    R_390_GOTPLT20 =          59,	//< 20 bit offset to jump slot.  
+    R_390_TLS_GOTIE20 =       60,	//< 20 bit GOT offset for static TLS block offset.  
+    /* Keep this the last entry.  */
+    R_390_NUM =               61,
+
+/* CRIS relocations.  */
+    R_CRIS_NONE =             0,
+    R_CRIS_8 =                1,
+    R_CRIS_16 =               2,
+    R_CRIS_32 =               3,
+    R_CRIS_8_PCREL =          4,
+    R_CRIS_16_PCREL =         5,
+    R_CRIS_32_PCREL =         6,
+    R_CRIS_GNU_VTINHERIT =    7,
+    R_CRIS_GNU_VTENTRY =      8,
+    R_CRIS_COPY =             9,
+    R_CRIS_GLOB_DAT =         10,
+    R_CRIS_JUMP_SLOT =        11,
+    R_CRIS_RELATIVE =         12,
+    R_CRIS_16_GOT =           13,
+    R_CRIS_32_GOT =           14,
+    R_CRIS_16_GOTPLT =        15,
+    R_CRIS_32_GOTPLT =        16,
+    R_CRIS_32_GOTREL =        17,
+    R_CRIS_32_PLT_GOTREL =    18,
+    R_CRIS_32_PLT_PCREL =     19,
+    R_CRIS_NUM =              20,
+
+/* AM33 relocations.  */
+    R_MN10300_NONE =          0,	//< No reloc.  
+    R_MN10300_32 =            1,	//< Direct 32 bit.  
+    R_MN10300_16 =            2,	//< Direct 16 bit.  
+    R_MN10300_8 =             3,	//< Direct 8 bit.  
+    R_MN10300_PCREL32 =       4,	//< PC-relative 32-bit.  
+    R_MN10300_PCREL16 =       5,	//< PC-relative 16-bit signed.  
+    R_MN10300_PCREL8 =        6,	//< PC-relative 8-bit signed.  
+    R_MN10300_GNU_VTINHERIT = 7,	//< Ancient C++ vtable garbage... 
+    R_MN10300_GNU_VTENTRY =   8,	//< ... collection annotation.  
+    R_MN10300_24 =            9,	//< Direct 24 bit.  
+    R_MN10300_GOTPC32 =       10,	//< 32-bit PCrel offset to GOT.  
+    R_MN10300_GOTPC16 =       11,	//< 16-bit PCrel offset to GOT.  
+    R_MN10300_GOTOFF32 =      12,	//< 32-bit offset from GOT.  
+    R_MN10300_GOTOFF24 =      13,	//< 24-bit offset from GOT.  
+    R_MN10300_GOTOFF16 =      14,	//< 16-bit offset from GOT.  
+    R_MN10300_PLT32 =         15,	//< 32-bit PCrel to PLT entry.  
+    R_MN10300_PLT16 =         16,	//< 16-bit PCrel to PLT entry.  
+    R_MN10300_GOT32 =         17,	//< 32-bit offset to GOT entry.  
+    R_MN10300_GOT24 =         18,	//< 24-bit offset to GOT entry.  
+    R_MN10300_GOT16 =         19,	//< 16-bit offset to GOT entry.  
+    R_MN10300_COPY =          20,	//< Copy symbol at runtime.  
+    R_MN10300_GLOB_DAT =      21,	//< Create GOT entry.  
+    R_MN10300_JMP_SLOT =      22,	//< Create PLT entry.  
+    R_MN10300_RELATIVE =      23,	//< Adjust by program base.  
+    R_MN10300_NUM =           24,
+
+/* AMD x86-64 relocations.  */
+    R_X86_64_NONE =           0,	//< No reloc 
+    R_X86_64_64 =             1,	//< Direct 64 bit  
+    R_X86_64_PC32 =           2,	//< PC relative 32 bit signed 
+    R_X86_64_GOT32 =          3,	//< 32 bit GOT entry 
+    R_X86_64_PLT32 =          4,	//< 32 bit PLT address 
+    R_X86_64_COPY =           5,	//< Copy symbol at runtime 
+    R_X86_64_GLOB_DAT =       6,	//< Create GOT entry 
+    R_X86_64_JUMP_SLOT =      7,	//< Create PLT entry 
+    R_X86_64_RELATIVE =       8,	//< Adjust by program base 
+    R_X86_64_GOTPCREL =       9,	//< 32 bit signed PC relative offset to GOT 
+    R_X86_64_32 =             10,	//< Direct 32 bit zero extended 
+    R_X86_64_32S =            11,	//< Direct 32 bit sign extended 
+    R_X86_64_16 =             12,	//< Direct 16 bit zero extended 
+    R_X86_64_PC16 =           13,	//< 16 bit sign extended pc relative 
+    R_X86_64_8 =              14,	//< Direct 8 bit sign extended  
+    R_X86_64_PC8 =            15,	//< 8 bit sign extended pc relative 
+    R_X86_64_DTPMOD64 =       16,	//< ID of module containing symbol 
+    R_X86_64_DTPOFF64 =       17,	//< Offset in module's TLS block 
+    R_X86_64_TPOFF64 =        18,	//< Offset in initial TLS block 
+    R_X86_64_TLSGD =          19,	//< 32 bit signed PC relative offset to two GOT entries for GD symbol 
+    R_X86_64_TLSLD =          20,	//< 32 bit signed PC relative offset to two GOT entries for LD symbol 
+    R_X86_64_DTPOFF32 =       21,	//< Offset in TLS block 
+    R_X86_64_GOTTPOFF =       22,	//< 32 bit signed PC relative offset to GOT entry for IE symbol 
+    R_X86_64_TPOFF32 =        23,	//< Offset in initial TLS block 
+    R_X86_64_NUM =            24,
+
+/* M32R relocs.  */
+    R_M32R_NONE =             0,	//< No reloc. 
+    R_M32R_16 =               1,	//< Direct 16 bit. 
+    R_M32R_32 =               2,	//< Direct 32 bit. 
+    R_M32R_24 =               3,	//< Direct 24 bit. 
+    R_M32R_10_PCREL =         4,	//< PC relative 10 bit shifted. 
+    R_M32R_18_PCREL =         5,	//< PC relative 18 bit shifted. 
+    R_M32R_26_PCREL =         6,	//< PC relative 26 bit shifted. 
+    R_M32R_HI16_ULO =         7,	//< High 16 bit with unsigned low. 
+    R_M32R_HI16_SLO =         8,	//< High 16 bit with signed low. 
+    R_M32R_LO16 =             9,	//< Low 16 bit. 
+    R_M32R_SDA16 =            10,	//< 16 bit offset in SDA. 
+    R_M32R_GNU_VTINHERIT =    11,
+    R_M32R_GNU_VTENTRY =      12,
+/* M32R relocs use SHT_RELA.  */
+    R_M32R_16_RELA =          33,	//< Direct 16 bit. 
+    R_M32R_32_RELA =          34,	//< Direct 32 bit. 
+    R_M32R_24_RELA =          35,	//< Direct 24 bit. 
+    R_M32R_10_PCREL_RELA =    36,	//< PC relative 10 bit shifted. 
+    R_M32R_18_PCREL_RELA =    37,	//< PC relative 18 bit shifted. 
+    R_M32R_26_PCREL_RELA =    38,	//< PC relative 26 bit shifted. 
+    R_M32R_HI16_ULO_RELA =    39,	//< High 16 bit with unsigned low 
+    R_M32R_HI16_SLO_RELA =    40,	//< High 16 bit with signed low 
+    R_M32R_LO16_RELA =        41,	//< Low 16 bit 
+    R_M32R_SDA16_RELA =       42,	//< 16 bit offset in SDA 
+    R_M32R_RELA_GNU_VTINHERIT = 43,
+    R_M32R_RELA_GNU_VTENTRY = 44,
+    R_M32R_REL32 =            45,	//< PC relative 32 bit.  
+    R_M32R_GOT24 =            48,	//< 24 bit GOT entry 
+    R_M32R_26_PLTREL =        49,	//< 26 bit PC relative to PLT shifted 
+    R_M32R_COPY =             50,	//< Copy symbol at runtime 
+    R_M32R_GLOB_DAT =         51,	//< Create GOT entry 
+    R_M32R_JMP_SLOT =         52,	//< Create PLT entry 
+    R_M32R_RELATIVE =         53,	//< Adjust by program base 
+    R_M32R_GOTOFF =           54,	//< 24 bit offset to GOT 
+    R_M32R_GOTPC24 =          55,	//< 24 bit PC relative offset to GOT 
+    R_M32R_GOT16_HI_ULO =     56,	//< High 16 bit GOT entry with unsigned low 
+    R_M32R_GOT16_HI_SLO =     57,	//< High 16 bit GOT entry with signed low 
+    R_M32R_GOT16_LO =         58,	//< Low 16 bit GOT entry 
+    R_M32R_GOTPC_HI_ULO =     59,	//< High 16 bit PC relative offset to GOT with unsigned low 
+    R_M32R_GOTPC_HI_SLO =     60,	//< High 16 bit PC relative offset to GOT with signed low 
+    R_M32R_GOTPC_LO =         61,	//< Low 16 bit PC relative offset to GOT 
+    R_M32R_GOTOFF_HI_ULO =    62,	//< High 16 bit offset to GOT with unsigned low 
+    R_M32R_GOTOFF_HI_SLO =    63,	//< High 16 bit offset to GOT with signed low 
+    R_M32R_GOTOFF_LO =        64,	//< Low 16 bit offset to GOT 
+    R_M32R_NUM =              256,	//< Keep this the last entry. 
+
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_object.hh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_object.hh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_object.hh	(revision 283)
@@ -0,0 +1,163 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_OBJECT_HH_
+#define ELFPP_OBJECT_HH_
+
+#include <string>
+#include <vector>
+
+#include <dpp/linked_list>
+
+#include "elfpp.hh"
+#include "elfpp_bits.hh"
+
+namespace elfpp
+{
+  class section;
+  class symbol;
+  class elf_access;
+  template <typename bits_t, int width> class elfn_access;
+
+  /** 
+      @short ELF object file class
+      @header elfpp/object
+   */
+  class object
+  {
+    template <typename, int> friend class elfn_access;
+    friend class section;
+  public:
+
+    /** Create an empty elf object */
+    object(e_machine_e machine,
+	   ei_class_e word_width = ELFCLASSNONE,
+	   ei_data_e byte_order = ELFDATANONE);
+
+    /** Create a new elf object and load sections from file. */
+    object(const std::string &filename);
+    
+    /** Create a new elf object  */
+    object();
+
+    /** Copy all header fields of obj and set the access_ variable*/
+    void copy_info(object& obj, size_t word_width = 0);
+
+    ~object();
+
+    /**
+       Parse symbol and relocation tables sections and create
+       associated object representation. Parsed table sections are
+       discarded and will be regenerated when writing elf file.
+     */
+    void parse_symbol_table();
+
+    /**
+       @this creates symbols for all area not covered by a symbol in
+       allocatable sections.
+     */
+    void create_orphan_symbols();
+
+    /**
+       @this loads symbol data from section content to symbol content
+       storage.
+     */
+    void load_symbol_data();
+
+    /**
+       @this update all relocations to be relative to mangled
+       symbols. Sections will be updated from symbol content when
+       writing elf file.
+    */
+    void set_relative_relocs();
+
+    /** Add a new section to object. */
+    void add_section(section &sec);
+
+    /** Remove a section from object. */
+    void remove_section(section &sec);
+
+    /** Get first section with given name. */
+    section & get_section(const std::string &name);
+
+    /** Return section table container. */
+    inline dpp::linked_list<section> & get_section_table();
+
+    /** Add a new segment to object. */
+    void add_segment(segment &seg);
+
+    /** Return section table container. */
+    inline dpp::linked_list<segment> & get_segment_table();
+
+    /** Add a new symbol to object. Symbol must be stored per
+	section. Only symbol without associated section must be added
+	to object. */
+    void add_symbol(symbol &sym);
+
+    /** Remove a section independent symbol from object. */
+    void remove_symbol(symbol &sym);
+
+    /** Get section independent symbol by name. */
+    inline symbol & get_symbol(const std::string &name);
+
+    /** Get section independent symbols table. */
+    inline const sym_tab_map_t & get_symbol_table() const;
+
+    /** Write elf object to file. Symbol and relocation table may be
+	generated from object representation if available. Sections
+	content are updated with symbols content. */
+    void write(const std::string &filename);
+
+    e_machine_e get_machine();
+    ei_class_e get_word_width();
+    ei_data_e get_byteorder();
+
+  private:
+
+    void set_relative_relocs(symbol *sym);
+
+    static ei_class_e get_word_width(e_machine_e machine);
+    static ei_data_e get_byte_order(e_machine_e machine);
+
+    dpp::linked_list<section> section_tab_;
+    dpp::linked_list<segment> segment_tab_;
+
+    ei_class_e word_width_;
+    ei_data_e byteorder_;
+    ei_osabi_e os_abi_;
+    uint8_t abi_ver_;
+    e_type_e type_;
+    e_machine_e machine_;
+
+    elf_access *access_;
+
+    bool rel_with_addend_;
+    bool generate_symtab_;
+    std::vector<section *> secidx_;
+    std::vector<symbol *> symidx_;
+    uint64_t entry_;
+    unsigned int flags_;
+    sym_tab_map_t sym_tab_;
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_object.hxx
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_object.hxx	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_object.hxx	(revision 283)
@@ -0,0 +1,57 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_OBJECT_HXX_
+#define ELFPP_OBJECT_HXX_
+
+#include <stdexcept>
+
+namespace elfpp
+{
+
+  symbol & object::get_symbol(const std::string &name)
+  {
+    sym_tab_map_t::iterator i = sym_tab_.find(name);
+
+    if (i == sym_tab_.end())
+      throw std::runtime_error("no such symbol name");
+
+    return *i->second;
+  }
+
+  const sym_tab_map_t & object::get_symbol_table() const
+  {
+    return sym_tab_;
+  }
+
+  dpp::linked_list<section> & object::get_section_table()
+  {
+    return section_tab_;
+  }
+
+  dpp::linked_list<segment> & object::get_segment_table()
+  {
+    return segment_tab_;
+  }
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_reloc.hh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_reloc.hh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_reloc.hh	(revision 283)
@@ -0,0 +1,102 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_RELOC_HH_
+#define ELFPP_RELOC_HH_
+
+#include <iostream>
+
+#include <dpp/linked_list>
+
+#include "elfpp.hh"
+#include "elfpp_bits.hh"
+
+namespace elfpp
+{
+
+  class reloc;
+  class symbol;
+  class section;
+  template <typename bits_t, int width> class elfn_access;
+
+  std::ostream & operator<<(std::ostream &o, const reloc &v);
+
+  /** 
+      @short ELF relocation class
+      @header elfpp/reloc
+   */
+  class reloc : public reloc_table_t::item_type,
+		public reloc_modlist_t::item_type
+  {
+    friend class section;
+    friend class symbol;
+    template <typename, int> friend class elfn_access;
+    friend std::ostream & operator<<(std::ostream &o, const reloc &v);
+
+  public:
+    reloc();
+    ~reloc();
+
+    /** Set pointer to mangled symbol. Relocation offset become
+	relative to mangled symbol value when set. */
+    void set_mangled_symbol(symbol *s);
+    /** Get pointer to mangled symbol. */
+    inline symbol * get_mangled_symbol() const;
+
+    /** Set relocation symbol */
+    void set_symbol(symbol *s);
+    /** Get relocation symbol */
+    inline symbol * get_symbol() const;
+
+    /** Set relocation section */
+    inline void set_section(section *s);
+    /** Get relocation section */
+    inline section * get_section() const;
+
+    /** Set relocation type */
+    inline void set_type(enum reloc_e type);
+    /** Get relocation type */
+    inline enum reloc_e get_type() const;
+
+    /** Set relocation addend */
+    inline void set_addend(int64_t addend);
+    /** Get relocation addend */
+    inline int64_t get_addend() const;
+
+    /** Set relocation offset. Relocation offset is relative to
+	mangled symbol value if available. It is relative to section
+	if no mangled symbol is defined. */
+    inline void set_offset(uint64_t offset);
+    /** Get relocation offset */
+    inline uint64_t get_offset() const;
+
+  private:
+    symbol *sym_mod_;
+    symbol *sym_;
+    section *sec_;
+    enum reloc_e type_;
+    int64_t addend_;
+    uint64_t offset_;
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_reloc.hxx
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_reloc.hxx	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_reloc.hxx	(revision 283)
@@ -0,0 +1,75 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+namespace elfpp
+{
+
+  symbol * reloc::get_mangled_symbol() const
+  {
+    return sym_mod_;
+  }
+
+  symbol * reloc::get_symbol() const
+  {
+    return sym_;
+  }
+
+  void reloc::set_section(section *s)
+  {
+    sec_ = s;
+  }
+
+  section * reloc::get_section() const
+  {
+    return sec_;
+  }
+
+  void reloc::set_type(enum reloc_e type)
+  {
+    type_ = type;
+  }
+
+  enum reloc_e reloc::get_type() const
+  {
+    return type_;
+  }
+
+  void reloc::set_addend(int64_t addend)
+  {
+    addend_ = addend;
+  }
+
+  int64_t reloc::get_addend() const
+  {
+    return addend_;
+  }
+
+  void reloc::set_offset(uint64_t offset)
+  {
+    offset_ = offset;
+  }
+
+  uint64_t reloc::get_offset() const
+  {
+    return offset_;
+  }
+
+}
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_section.hh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_section.hh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_section.hh	(revision 283)
@@ -0,0 +1,170 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_SECTION_HH_
+#define ELFPP_SECTION_HH_
+
+#include <string>
+#include <map>
+#include <stdint.h>
+
+#include "elfpp.hh"
+#include "elfpp_bits.hh"
+
+namespace elfpp
+{
+
+  class object;
+  class section;
+  class symbol;
+  class reloc;
+
+  std::ostream & operator<<(std::ostream &o, const section &v);
+
+  /** 
+      @short ELF section class
+      @header elfpp/section
+   */
+  class section : public section_table_t::item_type
+  {
+    template <typename, int> friend class elfn_access;
+    friend std::ostream & operator<<(std::ostream &o, const section &v);
+    friend class symbol;
+    friend class object;
+
+  public:
+    /** @this creates a new section associated with given object */
+    section(object &obj, sh_type_e type);
+
+    ~section();
+
+    /** @this sets section name */
+    inline void set_name(const std::string &name);
+    /** @this gets section name */
+    inline const std::string & get_name() const;
+
+    /** @this gets section type */
+    inline sh_type_e get_type() const;
+
+    /** @this sets section flags */
+    inline void set_flags(sh_flags_e flags);
+    /** @this gets section flags */
+    inline sh_flags_e get_flags() const;
+
+    /** @this sets section address */
+    inline void set_vaddr(uint64_t vaddr);
+    /** @this gets section address */
+    inline uint64_t get_vaddr() const;
+
+    /** @this sets section size, reallocate section content buffer */
+    void set_size(size_t size);
+    /** @this gets section size */
+    inline size_t get_size() const;
+
+    /** @this sets section link to an other section */
+    inline void set_link(section *s);
+    /** @this gets section link */
+    inline section * get_link() const;
+    /** @this gets section with a link to this section, may be unreliable if
+	multiple links exits */
+    inline section * get_back_link() const;
+
+    /** @this sets section info as link to section */
+    inline void set_info(section *s);
+    /** @this gets section info as link to section */
+    inline section * get_info() const;
+    /** @this gets section info as back link to section */
+    inline section * get_back_info() const;
+
+    /** @this sets section info as last local symbol index */
+    inline void set_info_last(unsigned int last);
+    /** @this gets section info as last local symbol index */
+    inline unsigned int get_info_last();
+
+    /** @this sets section alignement */
+    inline void set_align(uint32_t align);
+    /** @this gets section alignement */
+    inline uint32_t get_align() const;
+
+    /** @this sets section entry size */
+    inline void set_entsize(uint32_t entsize);
+    /** @this sets section entry size */
+    inline uint32_t get_entsize() const;
+
+    /** @this sets pointer to section content buffer */
+    void set_content(void* a);
+    /** @this gets pointer to section content buffer */
+    inline uint8_t *get_content() const;
+
+    /** @this gets pointer to container segment if any */
+    segment *get_segment() const;
+
+    /** @this gets associated object */
+    inline object * get_object() const;
+
+    /** @this gets load address from segment info  */
+    uint64_t get_load_address() const;
+
+    inline off_t get_file_offset() const;
+
+    /** @this adds symbol to section */
+    void add_symbol(symbol &sym);
+    /** @this removes symbol from section */
+    void remove_symbol(symbol &sym);
+    /** @this gets symbol by name */
+    inline symbol & get_symbol(const std::string &name);
+    /** @this gets symbol containing given offset */
+    symbol & get_symbol(uint64_t offset);
+    /** @this gets symbol table */
+    inline const sym_tab_map_t & get_symbol_table() const;
+
+   private:
+    inline void set_file_offset(off_t a);
+
+    /** start of flags present in elf section entry */
+    std::string name_;
+    sh_type_e type_;
+    sh_flags_e flags_;
+    uint64_t vaddr_;
+    off_t offset_;
+    size_t size_;
+    section *link_;
+    union {
+      section *info_;
+      unsigned int info_last_;
+    };
+    uint32_t align_;
+    uint32_t entsize_;
+    /** end of flags present in elf section entry */
+
+    // index of section
+    unsigned int index_;
+
+    section *back_info_;	// link to associated relocation table
+    section *back_link_;	// link to associated relocation table
+    object *object_;
+    uint8_t *content_;
+    sym_tab_map_t sym_tab_;
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_section.hxx
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_section.hxx	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_section.hxx	(revision 283)
@@ -0,0 +1,171 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_SECTION_HXX_
+#define ELFPP_SECTION_HXX_
+
+#include <stdexcept>
+
+
+namespace elfpp
+{
+
+  void section::set_name(const std::string &name)
+  {
+    name_ = name;
+  }
+
+  const std::string & section::get_name() const
+  {
+    return name_;
+  }
+
+  sh_type_e section::get_type() const
+  {
+    return type_;
+  }
+
+  void section::set_flags(sh_flags_e flags)
+  {
+    flags_ = flags;
+  }
+
+  sh_flags_e section::get_flags() const
+  {
+    return flags_;
+  }
+
+  void section::set_vaddr(uint64_t vaddr)
+  {
+    vaddr_ = vaddr;
+  }
+
+  uint64_t section::get_vaddr() const
+  {
+    return vaddr_;
+  }
+
+  size_t section::get_size() const
+  {
+    return size_;
+  }
+
+  void section::set_align(uint32_t align)
+  {
+    align_ = align;
+  }
+
+  uint32_t section::get_align() const
+  {
+    return align_;
+  }
+
+  void section::set_link(section *s)
+  {
+    link_ = s;
+    s->back_info_ = this;
+  }
+
+  section * section::get_link() const
+  {
+    return link_;
+  }
+
+  section * section::get_back_link() const
+  {
+    return back_link_;
+  }
+
+  void section::set_info(section *s)
+  {
+    info_ = s;
+    if (s)
+      s->back_info_ = this;
+  }
+
+  section * section::get_info() const
+  {
+    return info_;
+  }
+
+  section * section::get_back_info() const
+  {
+    return back_info_;
+  }
+
+  void section::set_info_last(unsigned int last)
+  {
+    info_last_ = last;
+  }
+
+  unsigned int section::get_info_last()
+  {
+    return info_last_;
+  }
+
+  void section::set_entsize(uint32_t entsize)
+  {
+    entsize_ = entsize;
+  }
+
+  uint32_t section::get_entsize() const
+  {
+    return entsize_;
+  }
+  
+  uint8_t * section::get_content() const
+  {
+    return content_;
+  }
+
+  off_t section::get_file_offset() const
+  {
+    return offset_;
+  }
+
+  void section::set_file_offset(off_t a)
+  {
+    offset_ = a;
+  }
+
+  const sym_tab_map_t & section::get_symbol_table() const
+  {
+    return sym_tab_;
+  }
+
+  symbol & section::get_symbol(const std::string &name)
+  {
+    sym_tab_map_t::iterator i = sym_tab_.find(name);
+
+    if (i == sym_tab_.end())
+      throw std::runtime_error("no such symbol name");
+
+    return *i->second;
+  }
+
+  object * section::get_object() const
+  {
+    return object_;
+  }
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_segment.hh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_segment.hh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_segment.hh	(revision 283)
@@ -0,0 +1,92 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_SEGMENT_HH_
+#define ELFPP_SEGMENT_HH_
+
+#include <string>
+#include <map>
+#include <stdint.h>
+
+#include "elfpp.hh"
+#include "elfpp_bits.hh"
+
+namespace elfpp
+{
+  class object;
+  class segment;
+
+  std::ostream & operator<<(std::ostream &o, const segment &v);
+
+  /** 
+      @short ELF segment class
+      @header elfpp/segment
+   */
+  class segment : public segment_table_t::item_type
+  {
+    template <typename, int> friend class elfn_access;
+    friend std::ostream & operator<<(std::ostream &o, const segment &v);
+    friend class object;
+
+  public:
+    /** create a new segment associated with given object */
+    inline segment(object &obj);
+    inline ~segment();
+
+    inline p_type_e get_type() const;
+    inline void set_type(p_type_e e);
+
+    inline p_flags_e get_flags() const;
+    inline void set_flags(p_flags_e e);
+
+    inline uint64_t get_vaddr() const;
+    inline void set_vaddr(uint64_t a);
+
+    inline uint64_t get_paddr() const;
+    inline void set_paddr(uint64_t a);
+
+    inline size_t get_mem_size() const;
+    inline void set_mem_size(size_t a);
+
+    inline size_t get_file_size() const;
+    inline off_t get_file_offset() const;
+
+    inline size_t get_align() const;
+    inline void set_align(size_t a);
+
+    inline void set_file_offset(off_t a);
+    inline void set_file_size(size_t a);
+
+   private:
+
+    /** start of flags present in elf segment entry */
+    p_type_e type_;
+    p_flags_e flags_;
+    uint64_t vaddr_;
+    uint64_t paddr_;
+    size_t mem_size_;
+    size_t file_size_;
+    off_t offset_;
+    size_t align_;
+  };
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_segment.hxx
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_segment.hxx	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_segment.hxx	(revision 283)
@@ -0,0 +1,118 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_SEGMENT_HXX_
+#define ELFPP_SEGMENT_HXX_
+
+namespace elfpp
+{
+
+  segment::segment(object &obj)
+  {
+  }
+
+  segment::~segment()
+  {
+  }
+
+  p_type_e segment::get_type() const
+  {
+    return type_;
+  }
+
+  void segment::set_type(p_type_e e)
+  {
+    type_ = e;
+  }
+
+  p_flags_e segment::get_flags() const
+  {
+    return flags_;
+  }
+
+  void segment::set_flags(p_flags_e e)
+  {
+    flags_ = e;
+  }
+
+  uint64_t segment::get_vaddr() const
+  {
+    return vaddr_;
+  }
+
+  void segment::set_vaddr(uint64_t a)
+  {
+    vaddr_ = a;
+  }
+
+  uint64_t segment::get_paddr() const
+  {
+    return paddr_;
+  }
+
+  void segment::set_paddr(uint64_t a)
+  {
+    paddr_ = a;
+  }
+
+  size_t segment::get_mem_size() const
+  {
+    return mem_size_;
+  }
+
+  void segment::set_mem_size(size_t a)
+  {
+    mem_size_ = a;
+  }
+
+  size_t segment::get_file_size() const
+  {
+    return file_size_;
+  }
+
+  void segment::set_file_size(size_t a)
+  {
+    file_size_ = a;
+  }
+
+  off_t segment::get_file_offset() const
+  {
+    return offset_;
+  }
+
+  void segment::set_file_offset(off_t a)
+  {
+    offset_ = a;
+  }
+
+  size_t segment::get_align() const
+  {
+    return align_;
+  }
+
+  void segment::set_align(size_t a)
+  {
+    align_ = a;
+  }
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_symbol.hh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_symbol.hh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_symbol.hh	(revision 283)
@@ -0,0 +1,143 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_SYMBOL_HH_
+#define ELFPP_SYMBOL_HH_
+
+#include "elfpp.hh"
+#include "elfpp_bits.hh"
+
+#include <stdint.h>
+#include <string>
+#include <map>
+
+#include <dpp/linked_list>
+
+namespace elfpp
+{
+
+  class reloc;
+  class section;
+
+  class symbol;
+  std::ostream & operator<<(std::ostream &o, const symbol &v);
+
+  /** 
+      @short ELF symbol class
+      @header elfpp/symbol
+   */
+  class symbol
+  {
+    template <typename, int> friend class elfn_access;
+    friend std::ostream & operator<<(std::ostream &o, const symbol &v);
+    friend class reloc;
+
+  public:
+    /** @this creates a new symbol with given name */
+    symbol(const std::string &name);
+
+    ~symbol();
+
+    /** @this gets symbol name */
+    inline const std::string & get_name() const;
+
+    /** @this sets symbol section */
+    void set_section(section &sec);
+    /** @this gets symbol section */
+    inline section * get_section() const;
+    /** @this sets integer section index, must be used for special ndx values */
+    inline void set_section_ndx(unsigned int ndx);
+    /** @this gets integer section index */
+    inline unsigned int get_section_ndx() const;
+
+    /** @this gets symbol info field
+	@see get_type @see get_bind @see #ELF_ST_TYPE @see #ELF_ST_BIND */
+    inline uint8_t get_info() const;
+    /** @this sets symbol info field 
+	@see set_type @see set_bind @see #ELF_ST_TYPE @see #ELF_ST_BIND */
+    inline void set_info(uint8_t st_info);
+
+    /** @this gets symbol type decoded from info field
+     	@see get_info */
+    inline st_info_type_e get_type() const;
+    /** @this sets symbol type in info field
+     	@see set_info */
+    inline void set_type(st_info_type_e type);
+
+    /** @this gets symbol bind decoded from info field
+     	@see get_info */
+    inline st_info_bind_e get_bind() const;
+    /** @this sets symbol bind in info field
+     	@see set_info */
+    inline void set_bind(st_info_bind_e bind);
+
+    /** @this gets symbol "other" field */
+    inline uint8_t get_other() const;
+    /** @this sets symbol "other" field */
+    inline void set_other(uint8_t st_other);
+
+    /** @this gets symbol value field */
+    inline uint64_t get_value() const;
+    /** @this sets symbol value field */
+    inline void set_value(uint64_t val);
+
+    /** @this gets symbol size in bytes */
+    inline size_t get_size() const;
+    /** @this sets symbol size in bytes */
+    inline void set_size(size_t size);
+
+    /** @multiple @this gets relocations associated with this symbol */
+    inline const reloc_table_t & get_reloc_table() const;
+
+    /** @multiple @this gets relocations which are mangling this symbol */
+    inline const reloc_modlist_t & get_mangling_relocs() const;
+
+    /** @this allocates a symbol content buffer of symbol size and fill with
+	data from given pointer. no symbol content buffer is allocated
+	by default unless load_symbol_data() has been called on elf
+	object. section is updated with symbol content at symbol value
+	offset when elf file is written. */
+    void set_content(uint8_t *data);
+
+    /** @this gets symbol content buffer */
+    inline uint8_t * get_content() const;
+
+  private:
+    /** start of flags present in elf symbol entry */
+    std::string			name_;
+    uint64_t			value_;
+    size_t			size_;
+    uint8_t			info_;
+    uint8_t			other_;
+    section			*section_;
+    unsigned int		sec_ndx_;
+    /** end of flags present in elf symbol entry */
+
+    unsigned int		index_;
+
+    reloc_table_t		reloc_tab_;
+    reloc_modlist_t		reloc_mod_;
+    uint8_t			*content_;
+  };
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_symbol.hxx
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_symbol.hxx	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/elfpp_symbol.hxx	(revision 283)
@@ -0,0 +1,125 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#ifndef ELFPP_SYMBOL_HXX_
+#define ELFPP_SYMBOL_HXX_
+
+namespace elfpp
+{
+
+  const std::string & symbol::get_name() const
+  {
+    return name_;
+  }
+
+  section * symbol::get_section() const
+  {
+    return section_;
+  }
+
+  void symbol::set_section_ndx(unsigned int ndx)
+  {
+    sec_ndx_ = ndx;
+  }
+
+  unsigned int symbol::get_section_ndx() const
+  {
+    return sec_ndx_;
+  }
+
+  uint8_t symbol::get_info() const
+  {
+    return info_;
+  }
+
+  void symbol::set_info(uint8_t info)
+  {
+    info_ = info;
+  }
+
+  uint8_t symbol::get_other() const
+  {
+    return other_;
+  }
+
+  void symbol::set_other(uint8_t other)
+  {
+    other_ = other;
+  }
+
+  uint64_t symbol::get_value() const
+  {
+    return value_;
+  }
+
+  size_t symbol::get_size() const
+  {
+    return size_;
+  }
+
+  uint8_t * symbol::get_content() const
+  {
+    return content_;
+  }
+
+  void symbol::set_value(uint64_t val)
+  {
+    value_ = val;
+  }
+
+  void symbol::set_size(size_t size)
+  {
+    size_ = size;
+  }
+
+  const reloc_table_t & symbol::get_reloc_table() const
+  {
+    return reloc_tab_;    
+  }
+
+  const reloc_modlist_t & symbol::get_mangling_relocs() const
+  {
+    return reloc_mod_;
+  }
+
+  st_info_type_e symbol::get_type() const
+  {
+    return ELF_ST_TYPE(info_);
+  }
+
+  void symbol::set_type(st_info_type_e type)
+  {
+    info_ = ELF_ST_INFO(get_bind(), type);
+  }
+
+  st_info_bind_e symbol::get_bind() const
+  {
+    return ELF_ST_BIND(info_);
+  }
+
+  void symbol::set_bind(st_info_bind_e bind)
+  {
+    info_ = ELF_ST_INFO(bind, get_type());
+  }
+
+}
+
+#endif
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/object
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/object	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/object	(revision 283)
@@ -0,0 +1,4 @@
+
+#include "elfpp_object.hh"
+#include "elfpp_object.hxx"
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/reloc
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/reloc	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/reloc	(revision 283)
@@ -0,0 +1,4 @@
+
+#include "elfpp_reloc.hh"
+#include "elfpp_reloc.hxx"
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/section
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/section	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/section	(revision 283)
@@ -0,0 +1,4 @@
+
+#include "elfpp_section.hh"
+#include "elfpp_section.hxx"
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/segment
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/segment	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/segment	(revision 283)
@@ -0,0 +1,4 @@
+
+#include "elfpp_segment.hh"
+#include "elfpp_segment.hxx"
+
Index: /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/symbol
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/symbol	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/libelfpp/elfpp/symbol	(revision 283)
@@ -0,0 +1,4 @@
+
+#include "elfpp_symbol.hh"
+#include "elfpp_symbol.hxx"
+
Index: /branch/giet_vm_ioc_drivers/memo/include/memo.h
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/memo.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/memo.h	(revision 283)
@@ -0,0 +1,123 @@
+/* -*- c++ -*-
+ *
+ * GIET_VM_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of GIET_VM, GNU LGPLv2.1.
+ * 
+ * GIET_VM is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * GIET_VM 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GIET_VM; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * GIET_VM_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, SoC
+ *         Mohamed Lamine Karaoui <Mohamed.Karaoui@lip6.fr>, 2012
+ *
+ */
+
+#ifndef GIET_VM_MEMO_H
+#define GIET_VM_MEMO_H
+
+#include  <stdlib.h>
+#include  <cstdlib>
+#include  <fcntl.h>
+#include  <unistd.h>
+#include  <cstdio>
+#include  <string.h>
+
+#include <string>
+#include <ios>
+#include <vector>
+#include <map>
+#include <fstream>
+
+#include <dpp/foreach>
+
+#include <elfpp/object>
+#include <elfpp/symbol>
+#include <elfpp/section>
+#include <elfpp/segment>
+#include <elfpp/elfpp_bits.hh>
+
+#include "stdint.h"
+#include "mapping_info.h"
+#include "pseg_handler.h"
+#include "path_handler.h"
+
+
+class MeMo
+{
+// TODO: make the name defined in the map_info relative to this wd.
+
+    std::string                                   m_path;       // map_info path name
+    std::string                                   m_wd;         // map_info directory TODO
+    std::string                                   m_simpleName; // map_info filename TODO
+    void*                                         m_data;       // map_info structure 
+    uintptr_t                                     m_addr;       // map_info address (virtual)
+    size_t                                        m_size;       // size of the structure
+    mutable std::map<std::string, elfpp::object*> m_loaders;
+    PSegHandler                                   m_psegh;
+    PathHandler                                   m_pathHandler;
+    bool                                          m_ginit;
+    elfpp::object*                                m_generator;
+
+    size_t load_bin(std::string filename, void* buffer);    
+    size_t bin_size(std::string filename);
+
+    elfpp::section* get_sect_by_addr(elfpp::object *loader, unsigned int addr);
+
+public:
+
+    MeMo( const std::string   &name, 
+          const size_t        pageSize = 4096);
+
+    ~MeMo();
+
+    void buildSoft(const std::string &filename);
+
+    void print( std::ostream &o ) const;
+
+    void print_mapping() const;
+
+    friend std::ostream &operator<<( std::ostream &o, const MeMo &s )
+    {
+        s.print(o);
+        return o;
+    }
+
+    // The following functions handle the map.bin structure
+    // They must keep synchronised with functions defined in boot_init.c.
+
+    mapping_cluster_t* get_cluster_base( mapping_header_t* header );
+    mapping_pseg_t* get_pseg_base( mapping_header_t* header );
+    mapping_vspace_t* get_vspace_base( mapping_header_t* header );
+    mapping_vseg_t* get_vseg_base( mapping_header_t* header );
+    mapping_vobj_t* get_vobj_base( mapping_header_t* header );
+    void print_mapping_info(void* desc);
+    void vseg_map( mapping_vseg_t* vseg);
+    void buildMap(void* desc);
+
+};
+
+
+#endif /* GIET_VM_MEMO_H */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/memo/include/path_handler.h
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/path_handler.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/path_handler.h	(revision 283)
@@ -0,0 +1,40 @@
+#ifndef PATH_H_
+#define PATH_H_
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <vector>
+#include <algorithm>
+#include <iterator>
+
+
+//class MeMo;
+
+class PathHandler
+{
+    //friend class MeMo;
+
+    std::string dirPath;
+    char delim;
+
+    std::vector<std::string>& split(const std::string &s, char delim, std::vector<std::string> &elems);
+
+    std::vector<std::string> split(const std::string &s, char delim);
+
+    //extract the path without the filename
+    std::string getFilePath(const std::string& filepath);
+
+public:
+
+    ~PathHandler();
+    PathHandler(const std::string& filepath);
+
+    //return the fullPath relative to where execution is done.
+    std::string getFullPath(const std::string& filepath) const;
+
+    std::string getFileName(const std::string& filepath);
+};
+
+
+#endif
Index: /branch/giet_vm_ioc_drivers/memo/include/pseg.h
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/pseg.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/pseg.h	(revision 283)
@@ -0,0 +1,150 @@
+/* -*- c++ -*-
+ *
+ * GIET-VM_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of the GIET-VMS, GNU LGPLv2.1.
+ * 
+ * The GIET-VM is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * THe GIET-VM 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * GIET-VM_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, SoC
+ *         Mohamed Lamine Karaoui <Mohamed.Karaoui@lip6.fr>, 2012
+ *          
+ */
+#ifndef GIET_MEMO_PSEG_H
+#define GIET_MEMO_PSEG_H
+
+#include <string>
+#include <vector>
+#include <ios>
+#include <elfpp/section>
+
+#include "stdint.h"
+#include "mapping_info.h"
+
+
+class MeMo;
+
+//////////
+class VSeg
+{
+    friend class PSegHandler;
+    friend class PSeg;
+    friend class MeMo;
+
+    typedef unsigned long long paddr_t;
+
+    std::string m_name;     // vseg name
+    std::string m_file;     // file name
+    uintptr_t   m_vma;      // Virtual address of the section to load in the binary file.
+    paddr_t     m_lma;      // Physical address  
+    size_t      m_length;
+    size_t      m_type;
+    bool        m_loadable; // loadable vseg ( code, data...)
+
+public:
+
+    int32_t     m_align;    // alignment of the first vobj
+    bool        m_ident;    // identity mapping required if true
+
+    const std::string& name() const;
+    const std::string& file() const;
+    uintptr_t vma() const;
+    paddr_t lma() const;
+    size_t length() const;
+    size_t type() const;
+
+    void print(std::ostream &o) const;
+    friend std::ostream &operator<<( std::ostream &o, const VSeg &s )
+    {
+        s.print(o);
+        return o;
+    }
+
+    VSeg& operator=(const VSeg &ref);
+
+    VSeg();
+    VSeg(const VSeg &ref);
+    VSeg(std::string&   binaryName, 
+         std::string&   name, 
+         uintptr_t      vma, 
+         size_t         length, 
+         bool           loadable, 
+         bool           ident);
+
+    ~VSeg();
+};
+
+//////////
+class PSeg
+{
+    std::string   m_name;
+    paddr_t       m_lma;
+    paddr_t       m_length;
+    size_t        m_type;
+
+    static size_t m_pageSize;
+
+public:
+
+    std::vector<VSeg> m_vsegs;
+
+    const std::string& name() const;
+    paddr_t lma() const;
+    paddr_t length() const;
+    size_t type() const;
+
+    void check() const;
+
+    void setName(std::string& name);
+    void setLma(paddr_t lma);
+    void setLength(paddr_t length);
+
+    static paddr_t align(paddr_t toAlign, unsigned alignPow2);
+    static paddr_t pageAlign(paddr_t toAlign);
+
+    static void setPageSize(size_t pg) {
+       m_pageSize = pg;
+    }
+    static size_t pageSize() {
+       return m_pageSize;
+    }
+
+    void add(VSeg& vseg);    //add a VSeg
+    void addIdent(VSeg& vseg);
+
+
+    void print(std::ostream &o) const;
+
+    friend std::ostream &operator<<(std::ostream &o, const PSeg &s )
+    {
+        s.print(o);
+        return o;
+    }
+    PSeg & operator=(const PSeg &ref);
+
+    PSeg();
+    PSeg(const PSeg &ref );
+    PSeg(const std::string &name);
+    PSeg(const std::string &name,
+         paddr_t lma,
+         paddr_t length,
+         size_t type);
+    ~PSeg();
+};
+
+
+#endif /* GIET_MEMO_PSEG_H */
Index: /branch/giet_vm_ioc_drivers/memo/include/pseg_handler.h
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/include/pseg_handler.h	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/include/pseg_handler.h	(revision 283)
@@ -0,0 +1,68 @@
+/* -*- c++ -*-
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, SoC
+ *         Mohamed Lamine Karaoui <Mohamed.Karaoui@lip6.fr>, 2012
+ *          
+ */
+#ifndef SOCLIB_PSEG_HANDLER_H_
+#define SOCLIB_PSEG_HANDLER_H_
+
+#include <string>
+#include <vector>
+#include <ios>
+
+#include "stdint.h"
+#include "mapping_info.h"
+#include "pseg.h"
+
+
+class MeMo;
+
+class PSegHandler
+{
+    friend class MeMo;
+
+    std::vector <PSeg> m_pSegs;
+
+public:
+
+    PSeg& get( size_t pos  );
+    const PSeg& getByAddr( uintptr_t segAddress ) const ;
+
+    //do some checking on all the Psegs. Called once the m_psegs is build.
+    void check() const;
+
+    void print( std::ostream &o ) const;
+
+    friend std::ostream &operator<<( std::ostream &o, const PSegHandler &s )
+    {
+        s.print(o);
+        return o;
+    }
+
+    PSegHandler();
+    ~PSegHandler();
+};
+
+
+#endif /* SOCLIB_PSEG_HANDLER_H_ */
Index: /branch/giet_vm_ioc_drivers/memo/main.cpp
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/main.cpp	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/main.cpp	(revision 283)
@@ -0,0 +1,69 @@
+#include <iostream>
+#include "memo.h"
+
+void print_help();
+
+int main(int argc, char *argv[])
+{
+    std::string map_path("");
+    std::string soft_path("soft.elf");
+    bool show = false;
+    bool show_map = false;
+
+    if (argc > 1)
+    {
+        for( int n=1 ; n<argc ; n++ )
+        {
+            if( (strcmp(argv[n],"-o") == 0) && (n+1<argc) )
+            {
+                soft_path = argv[n+1];
+                n++;
+            }
+            else 
+            if( (strcmp(argv[n],"-v") == 0))
+                show = true;
+            else 
+            if( (strcmp(argv[n],"-sm") == 0))
+                show_map = true;
+            else
+                map_path = std::string(argv[n]);
+            
+        }
+    }else
+    {
+        print_help();
+    }
+
+    //std::cout << map_path << std::endl;
+    //std::cout << soft_path << std::endl;
+
+    MeMo memo(map_path);
+
+    memo.buildSoft(soft_path);
+
+    if(show)
+        std::cout << memo << std::endl;
+
+    if(show_map)
+        memo.print_mapping();
+
+    std::cout << "Done: " << soft_path << std::endl;
+
+    return 0;
+}
+
+void print_help()
+{
+
+    std::cout << "***Arguments are:***" << std::endl;
+    std::cout << "  +mandatory argument:" << std::endl;
+    std::cout << "      `mappath`: mapping info structure path" << std::endl;
+    std::cout << "  +other argument:" << std::endl;
+    std::cout << "      \"-v\" for a verbose printing" << std::endl;
+    std::cout << "      \"-o\" output filename (default soft.bin)" << std::endl;
+    std::cout << "      \"-sm\" print the content of each physical segment" << std::endl;
+    std::cout << "***Examples:***" << std::endl;
+    std::cout << "./memo map.bin" << std::endl;
+    std::cout << "./memo map.bin -v" << std::endl;
+    std::cout << "./memo map.bin -v -o mysoft.bin -sm" << std::endl;
+}
Index: /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_access.cc
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_access.cc	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_access.cc	(revision 283)
@@ -0,0 +1,871 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#include <stdexcept>
+#include <iostream>
+#include <cassert>
+#include <algorithm>
+#include <cstring>
+
+#include <dpp/foreach>
+
+#include <elfpp/access>
+#include <elfpp/object>
+#include <elfpp/section>
+#include <elfpp/symbol>
+#include <elfpp/reloc>
+#include <elfpp/segment>
+
+namespace elfpp
+{
+
+  template <typename bits_t, int width>
+  void elfn_access<bits_t, width>::load_symtab(object &obj)
+  {
+    section &table = obj.get_section(".symtab");
+
+    if (table.get_type() != SHT_SYMTAB)
+      throw std::runtime_error("not a symbol table section");
+
+    // get symbol table content
+    elf_sym_t *symtab = (elf_sym_t*)table.get_content();
+    size_t count = table.get_size() / sizeof (elf_sym_t);
+
+    // get symbol string section
+    section &strtab = *table.get_link();
+    const char *symstr = (char*)strtab.get_content();
+
+    // create symbol objects from table
+    obj.symidx_.resize(count);
+
+    for (unsigned int i = 1; i < count; i++)
+      {
+	unsigned int idx = swap(symtab[i].st_shndx);
+
+	symbol *sym = new symbol(symstr + swap(symtab[i].st_name));
+
+	obj.symidx_[i] = sym;
+
+	sym->set_value(swap(symtab[i].st_value));
+	sym->set_size(swap(symtab[i].st_size));
+	sym->set_info(symtab[i].st_info);
+	sym->set_other(symtab[i].st_other);
+
+	if (idx > 0 && idx < SHN_LORESERVE)
+	  {
+	    section *symsec = obj.secidx_.at(idx);
+	    if (!symsec)
+	      continue;
+
+	    sym->set_section(*symsec);
+	    symsec->add_symbol(*sym);
+
+	    if (obj.type_ != ET_REL)
+	      sym->set_value(sym->get_value() - symsec->get_vaddr());
+
+	    if (symsec && sym->get_size() > 0 && symsec->get_type() != SHT_NOBITS)
+	      {
+		if (symsec->get_size() < sym->get_value())
+		  std::cerr << "elfpp: symbol value above section size " << sym->get_name()
+			    << ":" << std::hex << sym->get_value() << std::endl;
+		//		else
+		//		  sym->set_content(symsec->get_content() + sym->get_value());
+	      }
+	  }
+	else
+	  {
+	    sym->set_section_ndx(idx);
+	    obj.add_symbol(*sym);
+	  }
+      }
+
+    // discard symbol table sections
+    delete &table;
+    delete &strtab;
+  }
+
+  template <typename bits_t, int width>
+  void elfn_access<bits_t, width>::load_addend(const object &obj, reloc &r, const elf_rel_t *reltab,
+					       size_t count, int index, uint8_t *data)
+  {
+    //		  r->set_addend(rel_read(obj, type, sec->get_content() + ro));
+    uint64_t offset = swap(reltab[index].r_offset);
+    r.set_offset(offset);
+
+    switch (obj.machine_)
+      {
+      case EM_MIPS:
+	switch (r.get_type())
+	  {
+	  case R_MIPS_26:
+	    r.set_addend((swap(*(uint32_t*)(data + offset)) & 0x3ffffff) << 2);
+	    return;
+
+	  case R_MIPS_32:
+	    r.set_addend(swap(*(uint32_t*)(data + offset)));
+	    return;
+
+	  case R_MIPS_HI16: {
+	    int32_t value = (swap(*(uint32_t*)(data + offset)) & 0xffff) << 16;
+	    // get next LO16 relocation
+	    for (index++; index < (int)count && rel_type(swap(reltab[index].r_info)) != R_MIPS_LO16; index++)
+	      ;
+	    if (index != (int)count)
+	      {
+		offset = swap(reltab[index].r_offset);
+		value += (int16_t)swap(*(uint32_t*)(data + offset));
+		r.set_addend(value);
+	      }
+	    else
+	      {
+		std::cerr << "elfpp: can not find matching LO16 relocation" << std::endl;
+	      }
+	    return;
+	  }
+
+	  case R_MIPS_LO16: {
+	    int32_t value = (int16_t)swap(*(uint32_t*)(data + offset));
+	    // get prev HI16 relocation if any
+	    if (index > 0 && rel_type(swap(reltab[index - 1].r_info)) == R_MIPS_HI16)
+	      {
+		offset = swap(reltab[index - 1].r_offset);
+		value += (swap(*(uint32_t*)(data + offset)) & 0xffff) << 16;
+	      }
+	    r.set_addend(value);
+	    return;
+	  }
+
+	  default: ;
+	  }
+	break;
+
+      case EM_ARM:
+	switch (r.get_type())
+	  {
+	  case R_ARM_PC24:
+	    r.set_addend(((swap(*(uint32_t*)(data + offset)) & 0xffffff) << 2) + 8);
+	    return;
+
+	  case R_ARM_ABS32:
+	    r.set_addend(swap(*(uint32_t*)(data + offset)));
+	    return;
+
+	  default: ;
+	  }
+	break;
+
+      default: ;
+      }
+
+    std::cerr << "elfpp: unhandled relocation (machine=" << obj.machine_
+	      << ", type=" << r.get_type() << ")" << std::endl;
+    return;
+  }
+
+  template <typename bits_t, int width>
+  void elfn_access<bits_t, width>::rel_write(const object &obj, enum reloc_e type, void *data, int64_t value)
+  {
+    uint32_t mask;
+
+    switch (obj.machine_)
+      {
+      case EM_MIPS:
+	switch (type)
+	  {
+	  case R_MIPS_26:
+	    mask = 0x3ffffff;
+	    if (value & 0x3)
+	      std::cerr << "elfpp: R_MIPS_26 relocation with 2 LSB set" << std::endl;
+	    value >>= 2;
+	    goto done;
+
+	  case R_MIPS_32:
+	    mask = 0xffffffff;
+	    goto done;
+
+	  case R_MIPS_HI16:
+	    mask = 0xffff;
+	    value >>= 16;
+	    goto done;
+
+	  case R_MIPS_LO16:
+	    mask = 0xffff;
+	    goto done;
+
+	  default: ;
+	  }
+	break;
+
+      case EM_ARM:
+	switch (type)
+	  {
+	  case R_ARM_PC24:
+	    mask = 0x00ffffff;
+	    value = (value - 8) >> 2;
+	    goto done;
+
+	  case R_ARM_ABS32:
+	    mask = 0xffffffff;
+	    goto done;
+
+	  default: ;
+	  }
+	break;
+
+      default: ;
+      }
+
+    std::cerr << "elfpp: unhandled relocation (machine=" << obj.machine_ << ", type=" << type << ")" << std::endl;
+    return;
+
+  done:
+    *(uint32_t*)data = swap(mask & value) | (*(uint32_t*)data & swap(~mask));
+  }
+
+  template <typename bits_t, int width>
+  void elfn_access<bits_t, width>::load_reltab(object &obj)
+  {
+    // load all reloaction table sections
+
+    if (obj.type_ != ET_REL)
+      return;
+
+    FOREACH2(relsec, obj.get_section_table())
+      {
+	switch (relsec->get_type())
+	  {
+	  case SHT_REL: {
+	    elf_rel_t *reltab = (elf_rel_t*)relsec->get_content();
+	    size_t count = relsec->get_size() / sizeof (elf_rel_t);
+	    obj.rel_with_addend_ = false;
+
+	    for (unsigned int i = 0; i < count; i++)
+	      {
+		if (!rel_sym(swap(reltab[i].r_info)))
+		  continue;
+
+		reloc *r = new reloc();
+
+		section *sec = relsec->get_info();
+		symbol *sym = obj.symidx_.at(rel_sym(swap(reltab[i].r_info)));
+		assert(sym);
+
+		r->set_symbol(sym);
+		r->set_section(sec);
+
+		reloc_e type = rel_type(swap(reltab[i].r_info));
+		r->set_type(type);
+		load_addend(obj, *r, reltab, count, i, sec->get_content());
+	      }
+
+	    //		std::cerr << "elfpp: relocation " << i << " offset " << ro << " out of section" << std::endl;
+
+	    delete &*relsec;
+	    break;
+	  }
+
+	  case SHT_RELA: {
+	    elf_rela_t *reltab = (elf_rela_t*)relsec->get_content();
+	    size_t count = relsec->get_size() / sizeof (elf_rela_t);
+	    obj.rel_with_addend_ = true;
+
+	    for (unsigned int i = 0; i < count; i++)
+	      {
+		if (!rel_sym(swap(reltab[i].r_info)))
+		  continue;
+
+		reloc *r = new reloc();
+
+		section *sec = relsec->get_info();
+		symbol *sym = obj.symidx_[rel_sym(swap(reltab[i].r_info))];
+		assert(sym);
+
+		r->set_symbol(sym);
+		r->set_section(sec);
+
+		r->set_type(rel_type(swap(reltab[i].r_info)));
+		uint32_t ro = swap(reltab[i].r_offset);
+		r->set_offset(ro);
+		r->set_addend(swap(reltab[i].r_addend));
+	      }
+
+	    delete &*relsec;
+	    break;
+	  }
+
+	  default:
+	    break;
+	  }
+
+      }
+
+    obj.generate_symtab_ = true;
+  }
+
+  static bool sort_predicate(const symbol *a, const symbol *b)
+  {
+    return a->get_info() < b->get_info();
+  }
+
+  template <typename bits_t, int width>
+  void elfn_access<bits_t, width>::save_symtab(object &obj)
+  {
+    size_t shnum = 1;
+
+    // renumber current section table
+    FOREACH(s, obj.get_section_table())
+      s->index_ = shnum++;
+
+    // create symbol and associated string sections
+    section *symtab = new section(obj, SHT_SYMTAB);
+    section *strtab = new section(obj, SHT_STRTAB);
+    std::string str(1, '\0');
+
+    symtab->set_name(".symtab");
+    symtab->set_entsize(sizeof (elf_sym_t));
+    symtab->set_link(strtab);
+
+    strtab->set_name(".strtab");
+    strtab->set_flags(SHF_STRINGS);
+
+    obj.add_section(*symtab);
+    obj.add_section(*strtab);
+
+    // prepare sorted symbol array
+
+    unsigned int i = 0;
+    std::vector<symbol *> table;
+
+    table.resize(obj.get_symbol_table().size());
+
+    FOREACH(sym, obj.get_symbol_table())
+      table[i++] = sym->second;
+
+    FOREACH(sec, obj.get_section_table())
+      {
+	table.resize(i + sec->get_symbol_table().size());
+
+	FOREACH(sym, sec->get_symbol_table())
+	  table[i++] = sym->second;
+      }
+
+    sort(table.begin(), table.end(), sort_predicate);
+
+    for (i = 0; i < table.size(); i++)
+      {
+	if (ELF_ST_BIND(table[i]->get_info()) != STB_LOCAL)
+	  break;
+      }
+
+    symtab->set_info_last(i + 1);
+
+    // generate symbol table section content
+
+    std::vector<reloc*> reloclist[shnum];
+    elf_sym_t symdata[table.size() + 1];
+    i = 1;
+
+    std::memset(symdata, 0, sizeof(elf_sym_t));
+
+    FOREACH(sym_, table)
+      {
+	elf_sym_t &ent = symdata[i];
+	symbol *sym = *sym_;
+
+	swap(&ent.st_name, str.size());
+	str.append(sym->get_name().c_str(), sym->get_name().size() + 1);
+	swap(&ent.st_value, sym->get_value());
+	swap(&ent.st_size, sym->get_size());
+	ent.st_info = sym->get_info();
+	ent.st_other = sym->get_other();
+
+	FOREACH(rel, sym->reloc_tab_)
+	  reloclist[rel->get_section()->index_].push_back(&*rel);
+
+	if (sym->get_section())
+	  swap(&ent.st_shndx, sym->get_section()->index_);
+	else
+	  swap(&ent.st_shndx, sym->get_section_ndx());
+
+	sym->index_ = i++;
+      }
+
+    strtab->set_size(str.size());
+    std::memcpy(strtab->get_content(), str.data(), str.size());
+
+    symtab->set_size(sizeof(symdata));
+    std::memcpy(symtab->get_content(), symdata, sizeof(symdata));
+
+    // generate relocation table
+
+    FOREACH(sec, obj.get_section_table())
+      {
+	if (!sec->index_)
+	  continue;
+
+	std::vector<reloc*> &rl = reloclist[sec->index_];
+
+	if (rl.empty())
+	  continue;
+
+	section *reltab = new section(obj, obj.rel_with_addend_ ? SHT_RELA : SHT_REL);
+
+	reltab->set_entsize(sizeof (elf_rel_t));
+	reltab->set_link(symtab);
+	reltab->set_info(&*sec);
+
+	obj.add_section(*reltab);
+
+	if (obj.rel_with_addend_)
+	  {
+	    elf_rela_t reldata[rl.size()];
+
+	    reltab->set_name(".rela" + sec->get_name());
+	    i = 0;
+
+	    FOREACH(rel_, rl)
+	      {
+		reloc *rel = *rel_;
+
+		if (symbol *ms = rel->get_mangled_symbol())
+		  swap(&reldata[i].r_offset, ms->get_value() + rel->get_offset());
+		else
+		  swap(&reldata[i].r_offset, rel->get_offset());
+
+		swap(&reldata[i].r_info, rel_info(rel->get_symbol()->index_, rel->get_type()));
+		swap(&reldata[i].r_addend, rel->get_addend());
+		i++;
+	      }
+
+	    reltab->set_size(sizeof(reldata));
+	    std::memcpy(reltab->get_content(), reldata, sizeof(reldata));
+	  }
+	else
+	  {
+	    elf_rel_t reldata[rl.size()];
+
+	    reltab->set_name(".rel" + sec->get_name());
+	    i = 0;
+
+	    FOREACH(rel_, rl)
+	      {
+		reloc *rel = *rel_;
+
+		uint64_t ro = rel->get_offset();
+		if (symbol *ms = rel->get_mangled_symbol())
+		  {
+		    // relocation offset is relative to mangled symbol value
+		    if (ro < ms->get_size())
+		      rel_write(obj, rel->get_type(), ms->get_content() + ro, rel->get_addend());
+		    else
+		      std::cerr << "elfpp: relocation offset above mangled symbol size" << std::endl;
+		    ro += ms->get_value();
+		  }
+		else
+		  {
+		    // relocation offset is relative to mangled section
+		    if (ro < sec->get_size())
+		      rel_write(obj, rel->get_type(), sec->get_content() + ro, rel->get_addend());
+		    else
+		      std::cerr << "elfpp: relocation offset above section size" << std::endl;
+		  }
+
+		swap(&reldata[i].r_offset, ro);
+
+		swap(&reldata[i].r_info, rel_info(rel->get_symbol()->index_, rel->get_type()));
+		i++;
+	      }
+
+	    reltab->set_size(sizeof(reldata));
+	    std::memcpy(reltab->get_content(), reldata, sizeof(reldata));
+	  }
+
+      }
+  }
+
+  template <typename bits_t, int width>
+  void elfn_access<bits_t, width>::read(object &obj, FILE *file)
+  {
+    // read file header
+
+    elf_hdr_t head_;
+
+    fseek(file, 0, SEEK_SET);
+    if (fread(&head_, sizeof (head_), 1, file) != 1)
+      throw std::runtime_error("unable to read file");
+
+    obj.word_width_ = (ei_class_e)head_.e_ident[EI_CLASS];
+    obj.byteorder_ = byteorder_ = (ei_data_e)head_.e_ident[EI_DATA];
+    obj.os_abi_ = (ei_osabi_e)head_.e_ident[EI_OSABI];
+    obj.abi_ver_ = head_.e_ident[EI_ABIVERSION];
+    obj.type_ = (e_type_e)swap(head_.e_type);
+    obj.machine_ = (e_machine_e)swap(head_.e_machine);
+    obj.entry_ = swap(head_.e_entry);
+    obj.flags_ = swap(head_.e_flags);
+
+    // read segment table
+    size_t phnum = swap(head_.e_phnum);
+    elf_phdr_t phdr[phnum];
+
+    fseek(file, swap(head_.e_phoff), SEEK_SET);
+    if (fread(phdr, sizeof (elf_phdr_t), phnum, file) != phnum)
+      throw std::runtime_error("unable to read file");
+
+    // create segment objects
+
+    for (unsigned int i = 0; i < phnum; i++)
+      {
+	segment *s = new segment(obj);
+
+	s->set_type((p_type_e)swap(phdr[i].p_type));
+	s->set_file_offset(swap(phdr[i].p_offset));
+	s->set_vaddr(swap(phdr[i].p_vaddr));
+	s->set_paddr(swap(phdr[i].p_paddr));
+	s->set_mem_size(swap(phdr[i].p_memsz));
+	s->set_file_size(swap(phdr[i].p_filesz));
+	s->set_flags((p_flags_e)swap(phdr[i].p_flags));
+	s->set_align(swap(phdr[i].p_align));
+
+	obj.add_segment(*s);
+      }
+
+    // read section table
+    size_t shnum = swap(head_.e_shnum);
+    elf_shdr_t shdr[shnum];
+    obj.secidx_.resize(shnum);
+
+    fseek(file, swap(head_.e_shoff), SEEK_SET);
+
+    if (fread(shdr, sizeof (elf_shdr_t), shnum, file) != shnum)
+      throw std::runtime_error("unable to read file");
+
+    // create section objects
+
+    for (unsigned int i = 1; i < shnum; i++)
+      {
+	sh_type_e type = (sh_type_e)swap(shdr[i].sh_type);
+
+	section *s = new section(obj, type);
+	off_t offset = swap(shdr[i].sh_offset);
+
+	obj.secidx_[i] = s;
+	s->index_ = i;
+
+	s->set_flags((sh_flags_e)swap(shdr[i].sh_flags));
+	s->set_vaddr(swap(shdr[i].sh_addr));
+	s->set_file_offset(offset);
+	s->set_size(swap(shdr[i].sh_size));
+	s->set_align(swap(shdr[i].sh_addralign));
+	s->set_entsize(swap(shdr[i].sh_entsize));
+
+	if (type != SHT_NOBITS && s->get_size())
+	  {
+	    fseek(file, offset, SEEK_SET);
+	    if (fread(s->get_content(), s->get_size(), 1, file) != 1)
+	      throw std::runtime_error("unable to read file");
+	  }
+
+	obj.add_section(*s);
+      }
+
+    // update sections links
+
+    for (unsigned int i = 1; i < shnum; i++)
+      {
+	section &s = *obj.secidx_[i];
+
+	unsigned int link = swap(shdr[i].sh_link);
+
+	if (link)
+	  s.set_link(obj.secidx_.at(link));
+
+	unsigned int info = swap(shdr[i].sh_info);
+
+	switch (s.type_)
+	  {
+	  case SHT_REL:
+	  case SHT_RELA:
+	    if (info)
+	      s.set_info(obj.secidx_.at(info));
+	    break;
+
+	  case SHT_DYNSYM:
+	  case SHT_SYMTAB:
+	    s.set_info_last(info);
+	    break;
+
+	  default:
+	    ;
+	  }
+      }
+
+    // set sections names
+
+    unsigned int shstrndx = swap(head_.e_shstrndx);
+
+    if (shstrndx != SHN_UNDEF)
+      {
+	section &shstr = *obj.secidx_.at(shstrndx);
+	const char *str = (char*)shstr.get_content();
+
+	for (unsigned int i = 1; i < shnum; i++)
+	  obj.secidx_[i]->set_name(str + swap(shdr[i].sh_name));
+
+	delete &shstr;
+      }
+
+  }
+
+  template <typename bits_t, int width>
+  void elfn_access<bits_t, width>::create_segments(object &obj)
+  {
+     p_flags_e flag;
+
+    
+    FOREACH(sec, obj.get_section_table())
+      {
+        segment *s = new segment(obj);
+
+        if(!(sec->get_flags() & elfpp::SHF_ALLOC))
+        {
+            s->set_type(PT_NULL);
+            continue;
+        }
+        
+        s->set_type(PT_LOAD);
+        s->set_file_offset(0);//done while writing section in file
+#ifdef MEMO_DEBUG
+        std::cout << "seg building (" << std::hex << sec->get_vaddr() << ") for: " << *sec << std::endl;
+#endif
+        s->set_vaddr(sec->get_vaddr());
+        s->set_paddr(sec->get_vaddr());
+
+        s->set_mem_size(sec->get_size());
+        s->set_file_size(sec->get_size());
+
+            flag = PF_R ;//ALLOC ==> read ? 
+            flag = flag | (p_flags_e)(sec->get_flags() & SHF_WRITE)? PF_W : PF_R ; 
+            flag = flag | (p_flags_e)(sec->get_flags() & SHF_EXECINSTR)? PF_X : PF_R ; 
+        s->set_flags(flag);
+        s->set_align(0);//FIXME!
+
+#ifdef MEMO_DEBUG
+        std::cout <<"New segment " << s->get_file_size() << std::endl;
+#endif
+        obj.add_segment(*s);
+      }
+  }
+
+  template <typename bits_t, int width>
+  void elfn_access<bits_t, width>::write(object &obj, FILE *file)
+  {
+    byteorder_ = obj.byteorder_;
+
+    if (obj.generate_symtab_)
+      save_symtab(obj);
+
+    // create all segments
+
+    create_segments(obj);
+
+    // write symbol contents
+
+    FOREACH(sec, obj.get_section_table())
+      {
+	if (sec->get_type() == SHT_NOBITS)
+	  continue;
+
+	FOREACH(sym_, sec->get_symbol_table())
+	  {
+	    symbol *sym = sym_->second;
+
+	    if (!sym->get_content())
+	      continue;
+
+	    if (sec->get_size() < sym->get_value() + sym->get_size())
+	      sec->set_size(sym->get_value() + sym->get_size());
+
+	    std::memcpy(sec->get_content() + sym->get_value(), sym->get_content(), sym->get_size());
+	  }
+      }
+
+    elf_hdr_t head;
+
+    // create a new section name section
+
+    section *shstrtab = new section(obj, SHT_STRTAB);
+    shstrtab->set_name(".shstrtab");
+    shstrtab->set_flags(SHF_STRINGS);
+    obj.add_section(*shstrtab);
+
+    size_t shnum = 1;
+
+    FOREACH(s, obj.get_section_table())
+      s->index_ = shnum++;
+
+    std::string strtab(1, '\0');
+    unsigned int stridx[shnum];
+
+    stridx[0] = 0;
+
+    FOREACH(s, obj.get_section_table())
+      {
+	stridx[s->index_] = strtab.size();
+	strtab.append(s->get_name().c_str(), s->get_name().size() + 1);
+      }
+
+    shstrtab->set_size(strtab.size());
+    std::memcpy(shstrtab->get_content(), strtab.data(), strtab.size());
+
+    size_t phnum = shnum;//FIXME!:only relevent section
+    // update header
+
+    std::memset(head.e_ident, 0, sizeof(head.e_ident));
+    std::memcpy(head.e_ident, ELFMAG, 4);
+    head.e_ident[EI_CLASS] = obj.word_width_;
+    head.e_ident[EI_DATA] = byteorder_;
+    head.e_ident[EI_VERSION] = EV_CURRENT;
+    head.e_ident[EI_OSABI] = obj.os_abi_;
+    head.e_ident[EI_ABIVERSION] = obj.abi_ver_;
+
+    swap(&head.e_type, obj.type_);
+    swap(&head.e_machine, obj.machine_);
+    swap(&head.e_version, EV_CURRENT);
+    swap(&head.e_entry, obj.entry_);
+    swap(&head.e_phoff, sizeof (elf_hdr_t));
+    swap(&head.e_shoff, sizeof (elf_hdr_t)+ (sizeof(elf_phdr_t)*phnum));//!
+    swap(&head.e_flags, obj.flags_);
+    swap(&head.e_ehsize, sizeof (elf_hdr_t));
+    swap(&head.e_phentsize, sizeof (elf_phdr_t));
+    swap(&head.e_phnum, phnum);
+    swap(&head.e_shentsize, sizeof (elf_shdr_t));
+    swap(&head.e_shnum, shnum);
+    swap(&head.e_shstrndx, shstrtab->index_);
+
+    // update section table
+
+    elf_shdr_t shdr[shnum];
+
+    std::memset(shdr, 0, sizeof(shdr));
+
+    FOREACH(s, obj.get_section_table())
+      {
+	unsigned int i = s->index_;
+
+	swap(&shdr[i].sh_name, stridx[i]);
+
+	swap(&shdr[i].sh_type, s->get_type());
+	swap(&shdr[i].sh_flags, s->get_flags());
+	swap(&shdr[i].sh_addr, s->get_vaddr());
+
+
+	swap(&shdr[i].sh_size, s->get_size());
+	if (s->get_link())
+	  swap(&shdr[i].sh_link, s->get_link()->index_);
+
+	switch (s->get_type())
+	  {
+	  case SHT_REL:
+	  case SHT_RELA:
+	    assert(s->get_info());
+	    swap(&shdr[i].sh_info, s->get_info()->index_);
+	    break;
+
+	  case SHT_DYNSYM:
+	  case SHT_SYMTAB:
+	    swap(&shdr[i].sh_info, s->get_info_last());
+	  default:
+	    break;
+	  }
+
+	swap(&shdr[i].sh_addralign, s->get_align());
+	swap(&shdr[i].sh_entsize, s->get_entsize());
+      }
+
+    // update program header
+    elf_phdr_t phdr[phnum];
+
+    std::memset(phdr, 0, sizeof(phdr));
+
+    unsigned int i = 1;//to keep the same order as sections
+    FOREACH(s, obj.get_segment_table())
+      {
+
+	swap(&phdr[i].p_type, s->get_type());
+	swap(&phdr[i].p_flags, s->get_flags());
+	swap(&phdr[i].p_vaddr, s->get_vaddr());
+	swap(&phdr[i].p_paddr, s->get_paddr());
+
+
+	swap(&phdr[i].p_filesz, s->get_file_size());
+	swap(&phdr[i].p_memsz, s->get_mem_size());
+
+        
+	swap(&phdr[i].p_align, s->get_align());
+        //note: offset done while writing sections
+        i++;
+      }
+    //assert((i == phnum)and (i == shnum));
+
+    // write header to file
+
+    fseek(file, 0, SEEK_SET);
+    if (fwrite(&head, sizeof(head), 1, file) != 1)
+      throw std::runtime_error("unable to write header to file");
+
+    fseek(file, sizeof(phdr)+sizeof(shdr), SEEK_CUR);
+
+    // write sections to file
+
+    FOREACH(s, obj.get_section_table())
+      {
+        if (s->get_type() == SHT_NOBITS)
+          continue;
+
+#ifdef MEMO_DEBUG
+        std::cout << "offset: " << ftell(file) << " for " << *s << std::endl;
+        std::cout << std::hex << "paddr: " << phdr[s->index_].p_paddr << ", sect vaddr: " << s->get_vaddr() << "/" <<shdr[s->index_].sh_addr << std::endl;
+#endif
+	swap(&shdr[s->index_].sh_offset, ftell(file));
+	swap(&phdr[s->index_].p_offset, ftell(file));
+	if (s->get_size() && fwrite(s->get_content(), s->get_size(), 1, file) != 1)
+          throw std::runtime_error("unable to write section to file");
+      }
+    
+    // write program header to file
+
+    fseek(file, sizeof(head), SEEK_SET);
+    if (fwrite(phdr, sizeof(phdr), 1, file) != 1)
+      throw std::runtime_error("unable to write section table to file");
+
+    // write section table to file
+
+    //toDO:assert(cur_seek == phnum*sizeof(ph_t)+...)
+    //fseek(file, sizeof(phdr)+sizeof(head), SEEK_CUR);
+    if (fwrite(shdr, sizeof(shdr), 1, file) != 1)
+      throw std::runtime_error("unable to write section table to file");
+
+  }
+
+  template class elfn_access<elf32_bits_s, 32>;
+  template class elfn_access<elf64_bits_s, 64>;
+
+}
+
Index: /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_object.cc
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_object.cc	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_object.cc	(revision 283)
@@ -0,0 +1,412 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+
+#include <stdexcept>
+#include <cstring>
+
+#include <dpp/foreach>
+#include <dpp/interval_set>
+
+#include <elfpp/object>
+#include <elfpp/access>
+#include <elfpp/section>
+#include <elfpp/segment>
+#include <elfpp/symbol>
+#include <elfpp/reloc>
+
+namespace elfpp
+{
+
+  ei_class_e object::get_word_width(e_machine_e machine)
+  {
+    switch (machine)
+      {
+      case EM_386:
+	return ELFCLASS32;
+
+      case EM_X86_64:
+	return ELFCLASS64;
+
+      default:
+	throw std::runtime_error("unable to guess machine word width");
+      }
+  }
+
+  ei_data_e object::get_byte_order(e_machine_e machine)
+  {
+    switch (machine)
+      {
+      case EM_SPARC:
+	return ELFDATA2MSB;
+
+      case EM_X86_64:
+      case EM_386:
+	return ELFDATA2LSB;
+
+      default:
+	throw std::runtime_error("unable to guess machine byte order");
+      }
+  }
+
+  object::object(e_machine_e machine,
+		 ei_class_e word_width,
+		 ei_data_e byte_order)
+    : section_tab_(),
+      os_abi_(ELFOSABI_SYSV),
+      type_(ET_REL),
+      machine_(machine),
+      generate_symtab_(true),
+      entry_(0),
+      flags_(0)
+  {
+    switch (machine)
+      {
+      case EM_X86_64:
+      case EM_386:
+	rel_with_addend_ = false;
+	break;
+
+      default:
+	rel_with_addend_ = true;
+	break;
+      }
+
+    if (byte_order == ELFDATANONE)
+      byte_order = get_byte_order(machine);
+
+    if (word_width == ELFCLASSNONE)
+      word_width = get_word_width(machine);
+
+    switch (word_width)
+    {
+        case ELFCLASS32: {
+          static elf32_access a;
+          access_ = static_cast<elf_access*>(&a);
+          break;
+        }
+
+        case ELFCLASS64: {
+          static elf64_access a;
+          access_ = static_cast<elf_access*>(&a);
+          break;
+        }
+
+        default:
+          throw std::runtime_error("bad elf class");
+	}
+
+
+  }
+
+  object::object()
+    : section_tab_(),
+      os_abi_(ELFOSABI_SYSV),
+      type_(ET_REL),
+      machine_(EM_NONE),
+      generate_symtab_(true),
+      entry_(0),
+      flags_(0)
+  {}
+
+    
+
+  void object::copy_info(object& obj, size_t word_width)
+  {
+
+	if(word_width == 32)
+		this->word_width_  = ELFCLASS32;
+	else if(word_width == 64)
+	    this->word_width_  =  ELFCLASS64;
+	else
+	    this->word_width_  = obj.word_width_ ;
+
+    this->byteorder_  = obj.byteorder_ ;
+    this->machine_  = obj.machine_ ;
+    this->os_abi_   = obj.os_abi_ ;
+    this->abi_ver_  = obj.abi_ver_ ;
+    this->type_     = obj.type_ ;
+    this->flags_    = obj.flags_ ;
+
+    switch (this->word_width_)
+    {
+        case ELFCLASS32: {
+          static elf32_access a;
+          access_ = static_cast<elf_access*>(&a);
+          break;
+        }
+
+        case ELFCLASS64: {
+          static elf64_access a;
+          access_ = static_cast<elf_access*>(&a);
+          break;
+        }
+
+        default:
+          throw std::runtime_error("bad elf class");
+	}
+
+  }
+
+  object::object(const std::string &filename)
+    : generate_symtab_(false)
+  {
+    FILE *file = fopen(filename.c_str(), "rb");
+
+    if (!file)
+      throw std::runtime_error("unable to open file");
+
+    unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+
+    if (fread(e_ident, EI_NIDENT, 1, file) != 1)
+      throw std::runtime_error("unable to read file");
+
+    try {
+
+      if (std::memcmp(e_ident, ELFMAG, 4))
+	throw std::runtime_error("bad elf file header");
+
+      switch (e_ident[EI_CLASS])
+	{
+	case ELFCLASS32: {
+	  static elf32_access a;
+	  access_ = static_cast<elf_access*>(&a);
+	  break;
+	}
+
+	case ELFCLASS64: {
+	  static elf64_access a;
+	  access_ = static_cast<elf_access*>(&a);
+	  break;
+	}
+
+	default:
+	  throw std::runtime_error("bad elf class");
+	}
+
+      access_->read(*this, file);
+
+    } catch (...) {
+      fclose(file);
+      throw;
+    }
+
+    fclose(file);
+  }
+
+  object::~object()
+  {
+    FOREACH2(s, section_tab_)
+      delete &*s;
+
+    FOREACH(s, sym_tab_)
+      delete s->second;
+  }
+
+    e_machine_e object::get_machine()
+    {
+        return machine_;
+    }
+    ei_class_e object::get_word_width()
+    {
+        return  word_width_;
+    }
+    ei_data_e object::get_byteorder()
+    {
+        return byteorder_;
+    }
+
+  section & object::get_section(const std::string &name)
+  {
+    FOREACH(s, section_tab_)
+      if (s->get_name() == name)
+	return *s;
+
+    throw std::runtime_error("no such section");
+  }
+
+  void object::parse_symbol_table()
+  {
+    access_->load_symtab(*this);
+    access_->load_reltab(*this);
+  }
+
+  void object::set_relative_relocs(symbol *sym)
+  {
+    // find mangled symbol for each relocation and set offset relative
+    // to symbol value.
+    FOREACH2(k, sym->get_reloc_table())
+      {
+	if (k->get_mangled_symbol())
+	  continue;
+
+	if (sym->get_type() == STT_SECTION)
+	  {
+	    section *sS = sym->get_section();
+	    int64_t addend = k->get_addend();
+	    try {
+	      symbol &ss = sS->get_symbol(addend);
+	      k->set_symbol(&ss);
+	      k->set_addend(addend - ss.get_value());
+	    } catch (std::runtime_error &e) {
+#if 0
+	      std::cerr << e.what() << " at " << sS->get_name() << ":" << std::hex << addend
+			<< " while resolving section symbol addend at "
+			<< k->get_section()->get_name() << ":" << k->get_offset() << " type " << k->get_type() << std::endl;
+#endif
+	    }
+	  }
+
+	try {
+	  symbol &msym = k->get_section()->get_symbol(k->get_offset());
+	  // std::cerr << *i->second << " " << msym << std::endl;
+	  k->set_mangled_symbol(&msym);
+	  k->set_offset(k->get_offset() - msym.get_value());
+
+	} catch (std::runtime_error &e) {
+#if 0
+	  if (strncmp(k->get_section()->get_name().c_str(), ".debug", 6))
+	    std::cerr << e.what() << " at " << k->get_section()->get_name() << ":" << std::hex << k->get_offset() << std::endl;
+#endif
+	}
+
+      }
+  }
+
+  void object::create_orphan_symbols()
+  {
+    FOREACH(s, get_section_table())
+      {
+	if (!(s->get_flags() & SHF_ALLOC))
+	  continue;
+
+	typedef dpp::interval_set<uint32_t> is_t;
+	is_t is;
+
+	is |= is_t::interval_type(s->get_size(), (uint32_t)-1);
+
+	FOREACH(i, s->get_symbol_table())
+	  {
+	    uint32_t val = i->second->get_value();
+	    size_t size = i->second->get_size();
+
+	    if (size)
+	      is |= is_t::interval_type(val, val + size);
+	  }
+
+	is = ~is;
+
+	// create symbols for all orphan section areas in this object
+	FOREACH(i, is)
+	  {
+	    static int nosym_id = 0;
+	    char name[32];
+	    sprintf(name, "nosym_%i", nosym_id++);
+	    symbol *sym = new symbol(name);
+
+	    sym->set_value(i->low_bound());
+	    sym->set_size(i->high_bound() - i->low_bound());
+	    sym->set_section(*s);
+	    s->add_symbol(*sym);
+	  }
+      }
+  }
+
+  void object::load_symbol_data()
+  {
+    FOREACH(s, get_section_table())
+      {
+	if (s->get_type() == SHT_NOBITS)
+	  continue;
+
+	FOREACH(i, s->get_symbol_table())
+	  {
+	    symbol *j = i->second;
+
+	    // copy section data in each symbol content buffer
+	    size_t size = j->get_size();
+
+	    if (size != 0 && j->get_value() + size <= s->get_size())
+	      j->set_content(s->get_content() + j->get_value());
+	  }
+      }
+  }
+
+  void object::set_relative_relocs()
+  {
+    FOREACH(s, get_section_table())
+      {
+	FOREACH(i, s->get_symbol_table())
+	  set_relative_relocs(i->second);
+      }
+
+    FOREACH(i, get_symbol_table())
+      set_relative_relocs(i->second);
+  }
+
+  void object::write(const std::string &filename)
+  {
+    FILE *file = fopen(filename.c_str(), "wb");
+
+    if (!file)
+      throw std::runtime_error("unable to open file");
+
+    try {
+      access_->write(*this, file);
+    } catch (...) {
+      fclose(file);
+      throw;
+    }
+
+    fclose(file);
+  }
+
+  void object::add_section(section &sec)
+  {
+    section_tab_.push_back(sec);
+  }
+
+  void object::add_segment(segment &seg)
+  {
+    segment_tab_.push_back(seg);
+  }
+
+  void object::remove_section(section &sec)
+  {
+    sec.remove();
+  }
+
+  void object::add_symbol(symbol &sym)
+  {
+#if 0
+    if (sym.get_section())
+      sym.get_section()->add_symbol(sym);
+    else
+#endif
+      sym_tab_.insert(sym_tab_map_t::value_type(sym.get_name(), &sym));
+  }
+
+  void object::remove_symbol(symbol &sym)
+  {
+    sym_tab_.erase(sym.get_name());
+  }
+
+}
+
Index: /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_reloc.cc
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_reloc.cc	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_reloc.cc	(revision 283)
@@ -0,0 +1,70 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#include <elfpp/reloc>
+#include <elfpp/symbol>
+#include <elfpp/section>
+
+namespace elfpp
+{
+
+  reloc::reloc()
+    : sym_mod_(0),
+      sym_(0),
+      type_(R_NONE),
+      addend_(0)
+  {
+  }
+
+  reloc::~reloc()
+  {
+    if (!reloc_table_t::item_type::orphan())
+      reloc_table_t::item_type::remove();
+
+    if (!reloc_modlist_t::item_type::orphan())
+      reloc_modlist_t::item_type::remove();
+  }
+
+  void reloc::set_mangled_symbol(symbol *s)
+  {
+    if (sym_mod_)
+      reloc_modlist_t::item_type::remove();
+    sym_mod_ = s;
+    if (sym_mod_)
+      sym_mod_->reloc_mod_.push_back(*this);
+  }
+
+  void reloc::set_symbol(symbol *s)
+  {
+    if (sym_)
+      reloc_table_t::item_type::remove();
+    sym_ = s;
+    if (sym_)
+      sym_->reloc_tab_.push_back(*this);
+  }
+
+  std::ostream & operator<<(std::ostream &o, const reloc &r)
+  {
+    o << "[sym:" << *r.sym_ << " sec:" << *r.sec_ << " offset:" << r.offset_ << "]";
+    return o;
+  };
+
+}
+
Index: /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_section.cc
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_section.cc	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_section.cc	(revision 283)
@@ -0,0 +1,156 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+
+#include <iostream>
+#include <stdlib.h>
+#include <cstring>
+#include <stdlib.h>
+
+
+#include <dpp/foreach>
+
+#include <elfpp/section>
+#include <elfpp/object>
+#include <elfpp/segment>
+#include <elfpp/symbol>
+#include <elfpp/reloc>
+
+namespace elfpp
+{
+
+  section::section(object &obj, sh_type_e type)
+    : name_(),
+      type_(type),
+      flags_(SHF_NONE),
+      vaddr_(0),
+      size_(0),
+      link_(0),
+      info_(0),
+      align_(0),
+      entsize_(0),
+      index_(0),
+      back_info_(0),
+      back_link_(0),
+      object_(&obj),
+      content_(0),
+      sym_tab_()
+  {
+  }
+
+  section::~section()
+  {
+    if (!orphan())
+      remove();
+
+    if (content_)
+      free(content_);
+
+    object_->secidx_[index_] = 0;
+
+    FOREACH(s, sym_tab_)
+      delete s->second;
+  }
+
+  void section::set_size(size_t size)
+  {
+    if (type_ != SHT_NOBITS && size_ != size)
+      {
+	content_ = (uint8_t*)realloc(content_, size);
+
+	assert(content_ || size == 0);
+
+	if (size > size_)
+	  std::memset(content_ + size_, 0, size - size_);
+      }
+
+    size_ = size;
+  }
+
+  void section::set_content(void* a)
+  {
+    if(content_)
+        free(content_);
+    content_ = (uint8_t*) a;
+  }
+
+  void section::add_symbol(symbol &sym)
+  {
+    sym_tab_.insert(sym_tab_map_t::value_type(sym.get_name(), &sym));
+  }
+
+  symbol & section::get_symbol(uint64_t offset)
+  {
+    symbol *res = 0;
+
+    FOREACH(i, get_symbol_table())
+      {
+	symbol *j = i->second;
+
+	if (!j->get_size())
+	  continue;
+
+	if (j->get_value() <= offset && (!res || j->get_value() > res->get_value()))
+	  res = j;
+      }
+
+    if (!res)
+      throw std::runtime_error("no symbol found");
+
+    if (offset - res->get_value() >= res->get_size())
+      throw std::runtime_error("offset above symbol size");
+
+    return *res;
+  }
+
+  segment * section::get_segment() const
+  {
+    if (!object_)
+      throw std::runtime_error("section is not part of an object");
+
+    // find associated segment based on section content in elf file
+    FOREACH(s, object_->get_segment_table())
+      {
+	if (get_file_offset() >= s->get_file_offset() &&
+	    get_file_offset() < s->get_file_offset() + (off_t)s->get_file_size())
+	  return &*s;
+      }
+
+    return 0;
+  }
+
+  uint64_t section::get_load_address() const
+  {
+    segment *s = get_segment();
+
+    if (!s)
+      throw std::runtime_error("section is not located in a segment");
+
+    return vaddr_ - s->get_vaddr() + s->get_paddr();
+  }
+
+  std::ostream & operator<<(std::ostream &o, const section &s)
+  {
+    o << "[" << s.name_ << " addr:0x" << std::hex << s.vaddr_ << " size:" << std::dec << s.size_ << "]";
+    return o;
+  }
+
+}
+
Index: /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_symbol.cc
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_symbol.cc	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/libelfpp/elfpp_symbol.cc	(revision 283)
@@ -0,0 +1,76 @@
+/*
+    This file is part of Libelfpp.
+
+    Libelfpp is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    Libelfpp 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 Lesser General Public
+    License along with Libelfpp.  If not, see
+    <http://www.gnu.org/licenses/>.
+
+   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
+*/
+
+#include <iostream>
+#include <cstdlib>
+#include <cstring>
+
+#include <dpp/foreach>
+
+#include <elfpp/symbol>
+#include <elfpp/section>
+#include <elfpp/reloc>
+
+namespace elfpp
+{
+
+  symbol::symbol(const std::string &name)
+    : name_(name),
+      value_(0),
+      size_(0),
+      info_(0),
+      other_(0),
+      section_(0),
+      sec_ndx_(0),
+      reloc_tab_(),
+      content_(0)
+  {
+  }
+
+  symbol::~symbol()
+  {
+    if (content_)
+      std::free(content_);
+
+    FOREACH2(s, reloc_tab_)
+      delete &*s;
+    FOREACH(s, reloc_mod_)
+      delete &*s;
+  }
+
+  void symbol::set_section(section &sec)
+  {
+    section_ = &sec;
+  }
+
+  void symbol::set_content(uint8_t *data)
+  {
+    content_ = (uint8_t*)std::realloc(content_, size_);
+    std::memcpy(content_, data, size_);
+  }
+
+  std::ostream & operator<<(std::ostream &o, const symbol &s)
+  {
+    o << "[" << s.name_ << " val:" << s.value_ << " size:" << s.size_ << "]";
+    return o;
+  };
+
+}
+
Index: /branch/giet_vm_ioc_drivers/memo/src/memo.cpp
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/memo.cpp	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/memo.cpp	(revision 283)
@@ -0,0 +1,606 @@
+/* -*- c++ -*-
+ *
+ * GIET_VM_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of GIET_VM, GNU LGPLv2.1.
+ * 
+ * GIET_VM is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * GIET_VM 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GIET_VM; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * GIET_VM_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, SoC
+ *         Mohamed Lamine KARAOUI <Mohamed.Karaoui@lip6.fr>, 2012
+ */
+
+#include <string.h>
+#include <cassert>
+#include <sstream>
+#include <fstream>
+#include <ios>
+#include <iostream>
+#include <cstdarg>
+#include <cassert>
+#include <iomanip>
+
+
+#include "exception.h"
+#include "memo.h"
+
+//#define MOVER_DEBUG
+
+size_t PSeg::m_pageSize;
+
+
+////////////////////////////////////////////
+MeMo::MeMo(const std::string     &filename, 
+           const size_t          pageSize)
+        : m_path(filename),
+          m_pathHandler(filename),
+          m_ginit(false),
+          m_generator(new elfpp::object())
+{
+    PSeg::setPageSize(pageSize);
+
+    // loading map_info blob 
+    m_data = std::malloc(bin_size(m_path));
+    if ( !m_data )
+        throw exception::RunTimeError("malloc failed... No memory space");
+
+    m_size = load_bin(m_path, m_data);
+
+    // checking signature
+    mapping_header_t*   header = (mapping_header_t*)m_data; 
+    if((IN_MAPPING_SIGNATURE != header->signature))
+    {
+        std::cout  << "wrong signature " 
+                   << std::hex <<header->signature 
+                   << ", should be:"<< IN_MAPPING_SIGNATURE << std::endl;
+        exit(1);
+    }
+
+#ifdef MOVER_DEBUG
+    std::cout << "Binary file path: " << m_path << std::endl;
+    print_mapping_info(m_data);
+#endif
+
+    buildMap(m_data);
+    
+#ifdef MOVER_DEBUG
+    std::cout << "parsing done" << std::endl ;
+#endif
+
+#ifdef MOVER_DEBUG
+    print_mapping();
+    std::cout << *this << std::endl;
+#endif
+
+    m_psegh.check();
+#ifdef MOVER_DEBUG
+    std::cout << "checking done" << std::endl ;
+#endif
+
+}
+
+/////////////////////////////////////////
+void MeMo::print(std::ostream &o) const
+{
+    std::cout << "All sections:" << std::endl;
+    FOREACH(sect, m_generator->get_section_table())
+    {
+        assert(&*sect != NULL);
+        std::cout << *sect << std::endl; 
+    }
+}
+
+////////////////////////////////
+void MeMo::print_mapping() const
+{
+    std::cout << m_psegh << std::endl;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+elfpp::section* MeMo::get_sect_by_addr(elfpp::object *loader, unsigned int addr)
+{
+    FOREACH( sect, loader->get_section_table() )
+    {
+        assert(&*sect != NULL);
+        elfpp::sh_flags_e eflags = sect->get_flags();
+        if ( !(eflags & elfpp::SHF_ALLOC) )
+            continue;
+        if(sect->get_load_address() == addr) //load_addr ?
+        {
+            return (&*sect);
+        }
+    }
+    return NULL;
+}
+
+/////////////////////////////////////////////////
+void MeMo::buildSoft(const std::string &filename)
+{
+    if(!m_ginit)
+        throw exception::RunTimeError(std::string("Can't get generator! ") );
+
+    m_generator->write(filename);
+
+}
+
+/////////////////////////////////////////////////////////
+size_t MeMo::load_bin(std::string filename, void* buffer)
+{
+
+#ifdef MOVER_DEBUG
+    std::cout  << "Loading binary blob from file '" << filename << "'" << std::endl;
+#endif
+
+    std::ifstream input(filename.c_str(), std::ios_base::binary|std::ios_base::in);
+
+    if ( ! input.good() )
+        throw exception::RunTimeError(std::string("Can't open the file: ") + filename);
+
+    input.seekg( 0, std::ifstream::end );
+    size_t size = input.tellg();
+    input.seekg( 0, std::ifstream::beg );
+
+    if ( !buffer )
+        throw exception::RunTimeError("Empty buffer!");
+
+    input.read( (char*)buffer, size );
+
+    input.close();
+
+    return size;
+}
+
+
+/* get the size of the content of the filename */
+//////////////////////////////////////////
+size_t MeMo::bin_size(std::string filename)
+{
+
+#ifdef MOVER_DEBUG
+    std::cout  << "Trying to get the size of the binary blob '" << filename << "'" << std::endl;
+#endif
+
+    std::ifstream input(filename.c_str(), std::ios_base::binary|std::ios_base::in);
+
+    if ( ! input.good() )
+        throw exception::RunTimeError(std::string("Can't open the file: ") + filename);
+
+    input.seekg( 0, std::ifstream::end );
+    size_t size = input.tellg();
+    input.seekg( 0, std::ifstream::beg );
+
+    input.close();
+
+    return size;
+}
+
+
+/////////////
+MeMo::~MeMo()
+{
+    //std::cout << "Deleted MeMo " << *this << std::endl;
+    //std::free(m_data);//should be done by the elfpp driver since we passed the pointer
+    std::map<std::string, elfpp::object*>::iterator l;
+    for(l = m_loaders.begin(); l != m_loaders.end(); l++)
+    {
+        delete (*l).second;
+    }
+    //delete m_generator;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// various mapping_info data structure access functions
+/////////////////////////////////////////////////////////////////////////////
+mapping_cluster_t* MeMo::get_cluster_base( mapping_header_t* header )
+{
+    return   (mapping_cluster_t*) ((char*)header +
+                                  MAPPING_HEADER_SIZE);
+}
+/////////////////////////////////////////////////////////////////////////////
+mapping_pseg_t* MeMo::get_pseg_base( mapping_header_t* header )
+{
+    return   (mapping_pseg_t*)    ((char*)header +
+                                  MAPPING_HEADER_SIZE +
+                                  MAPPING_CLUSTER_SIZE*header->clusters);
+}
+/////////////////////////////////////////////////////////////////////////////
+mapping_vspace_t* MeMo::get_vspace_base( mapping_header_t* header )
+{
+    return   (mapping_vspace_t*)  ((char*)header +
+                                  MAPPING_HEADER_SIZE +
+                                  MAPPING_CLUSTER_SIZE*header->clusters +
+                                  MAPPING_PSEG_SIZE*header->psegs);
+}
+/////////////////////////////////////////////////////////////////////////////
+mapping_vseg_t* MeMo::get_vseg_base( mapping_header_t* header )
+{
+    return   (mapping_vseg_t*)    ((char*)header +
+                                  MAPPING_HEADER_SIZE +
+                                  MAPPING_CLUSTER_SIZE*header->clusters +
+                                  MAPPING_PSEG_SIZE*header->psegs +
+                                  MAPPING_VSPACE_SIZE*header->vspaces);
+}
+/////////////////////////////////////////////////////////////////////////////
+mapping_vobj_t* MeMo::get_vobj_base( mapping_header_t* header )
+{
+    return   (mapping_vobj_t*)    ((char*)header +
+                                  MAPPING_HEADER_SIZE +
+                                  MAPPING_CLUSTER_SIZE*header->clusters +
+                                  MAPPING_PSEG_SIZE*header->psegs +
+                                  MAPPING_VSPACE_SIZE*header->vspaces +
+                                  MAPPING_VSEG_SIZE*header->vsegs);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// print the content of the mapping_info data structure 
+////////////////////////////////////////////////////////////////////////
+void MeMo::print_mapping_info(void* desc)
+{
+    mapping_header_t*   header = (mapping_header_t*)desc;  
+
+    mapping_pseg_t*	    pseg    = get_pseg_base( header );;
+    mapping_vspace_t*	vspace  = get_vspace_base ( header );;
+    mapping_vseg_t*	    vseg    = get_vseg_base ( header );
+    mapping_vobj_t*	    vobj    = get_vobj_base ( header );
+
+    // header
+    std::cout << std::hex << "mapping_info" << std::dec << std::endl
+              << " + signature = " << header->signature << std::endl
+              << " + name      = " << (char*)header->name      << std::endl
+              << " + clusters  = " << header->clusters  << std::endl
+              << " + psegs     = " << header->psegs     << std::endl
+              << " + vspaces   = " << header->vspaces   << std::endl
+              << " + globals   = " << header->globals   << std::endl
+              << " + vsegs     = " << header->vsegs     << std::endl
+              << " + vobjs     = " << header->vsegs     << std::endl
+              << " + tasks     = " << header->tasks     << std::endl;
+
+    // psegs
+    for ( size_t pseg_id = 0 ; pseg_id < header->psegs ; pseg_id++ )
+    {
+        std::cout << "pseg " << pseg[pseg_id].name << std::hex << std::endl 
+                  << " + base   = " << pseg[pseg_id].base   << std::endl 
+                  << " + length = " << pseg[pseg_id].length << std::endl ;
+    }
+
+    // globals
+    for ( size_t vseg_id = 0 ; vseg_id < header->globals ; vseg_id++ )
+    {
+        std::cout << std::endl;
+        //std::cout << vseg[vseg_id].psegid << std::endl;
+        std::cout << "global vseg "   << vseg[vseg_id].name << std::hex << std::endl 
+                  << " + vbase    = " << vseg[vseg_id].vbase << std::endl 
+                  << " + length   = " << vseg[vseg_id].length << std::endl 
+                  << " + mode     = " << (size_t)vseg[vseg_id].mode << std::endl 
+                  << " + ident    = " << (bool)vseg[vseg_id].ident << std::endl 
+                  << " + psegname = " << pseg[vseg[vseg_id].psegid].name << std::endl;
+        for( size_t vobj_id = vseg[vseg_id].vobj_offset ; 
+                    vobj_id < vseg[vseg_id].vobj_offset + vseg[vseg_id].vobjs ; 
+                    vobj_id++ )
+        {
+            std::cout << "\t vobj "        << vobj[vobj_id].name    << std::endl
+                      << "\t + index   = " << std::dec << vobj_id   << std::endl
+                      << "\t + type    = " << vobj[vobj_id].type    << std::endl
+                      << "\t + length  = " << vobj[vobj_id].length  << std::endl
+                      << "\t + align   = " << vobj[vobj_id].align   << std::endl
+                      << "\t + binpath = " << vobj[vobj_id].binpath << std::endl
+                      << "\t + init    = " << vobj[vobj_id].init    << std::endl;
+        }
+    }
+
+    // vspaces
+    for ( size_t vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ )
+    {
+        std::cout << "***vspace "  << vspace[vspace_id].name   << std::endl 
+                  << " + vsegs = " <<  vspace[vspace_id].vsegs << std::endl 
+                  << " + vobjs = " <<  vspace[vspace_id].vobjs << std::endl 
+                  << " + tasks = " <<  vspace[vspace_id].tasks << std::endl;
+
+        for ( size_t vseg_id = vspace[vspace_id].vseg_offset ; 
+              vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs) ; 
+              vseg_id++ )
+        {
+            std::cout << "\t vseg " << vseg[vseg_id].name  << std::endl
+                      << "\t + vbase    = " << vseg[vseg_id].vbase             << std::endl
+                      << "\t + length   = " << vseg[vseg_id].length            << std::endl
+                      << "\t + mode     = " << (size_t)vseg[vseg_id].mode      << std::endl
+                      << "\t + ident    = " << (bool)vseg[vseg_id].ident       << std::endl
+                      << "\t + psegname = " << pseg[vseg[vseg_id].psegid].name << std::endl;
+            for(size_t vobj_id = vseg[vseg_id].vobj_offset ; 
+                       vobj_id < vseg[vseg_id].vobj_offset + vseg[vseg_id].vobjs ; 
+                       vobj_id++ )
+            {
+                std::cout << "\t\t vobj "      << vobj[vobj_id].name      << std::endl
+                          << "\t\t + index   = " << std::dec << vobj_id   << std::endl
+                          << "\t\t + type    = " << vobj[vobj_id].type    << std::endl
+                          << "\t\t + length  = " << vobj[vobj_id].length  << std::endl
+                          << "\t\t + align   = " << vobj[vobj_id].align   << std::endl
+                          << "\t\t + binpath = " << vobj[vobj_id].binpath << std::endl
+                          << "\t\t + init    = " << vobj[vobj_id].init    << std::endl;
+            }
+        }
+
+    }
+} // end print_mapping_info()
+
+
+//////////////////////////////////////////
+void MeMo::vseg_map( mapping_vseg_t* vseg)
+{
+    mapping_vobj_t * vobj = get_vobj_base((mapping_header_t*) m_data );
+    PSeg            * ps = &(m_psegh.get(vseg->psegid));
+    elfpp::section * sect = NULL;
+    size_t           cur_vaddr;
+    paddr_t          cur_length;
+    bool             first = true;
+    bool             aligned = false;
+    VSeg *           vSO = new VSeg;
+    mapping_vobj_t * cur_vobj;
+
+    vSO->m_name = std::string(vseg->name);
+    vSO->m_vma  = vseg->vbase;
+    vSO->m_lma  = 0;
+
+    cur_vaddr = vseg->vbase;
+    cur_length = 0; // curr_length of the vseg; a new vseg is necessarily aligned on a page boundary
+
+#ifdef MOVER_DEBUG
+    std::cout << "--------------- vseg_map "<< vseg->name <<" ------------------" << std::endl;
+#endif
+
+    for (size_t vobj_id = vseg->vobj_offset; 
+          vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++)
+    {
+        cur_vobj = &vobj[vobj_id];
+
+#ifdef MOVER_DEBUG
+        std::cout << std::hex << "current vobj("<< vobj_id <<"): " << cur_vobj->name 
+                  << " (" <<cur_vobj->vaddr << ")"
+                  << " size: "<< cur_vobj->length 
+                  << " type: " <<  cur_vobj->type << std::endl;
+#endif
+        if (cur_vobj->type == VOBJ_TYPE_BLOB)
+        {
+            size_t blob_size;
+            std::string filePath(m_pathHandler.getFullPath(std::string(cur_vobj->binpath)));
+
+#ifdef MOVER_DEBUG
+            std::cout << std::hex << "Handling: " << filePath << " ..." << std::endl;
+#endif
+
+            if (!filePath.compare(m_path))    // local blob: map_info
+            {
+#ifdef MOVER_DEBUG
+                std::cout << "Found the vseg of the mapping info" << std::endl;
+#endif
+                blob_size = this->m_size;
+                assert((blob_size >0) and "MAPPING INFO file is empty !?");
+            }
+            else
+            {
+#ifdef MOVER_DEBUG
+                std::cout << "Found an BLOB vseg" << std::endl;
+#endif
+                blob_size = bin_size(filePath);
+            }
+
+            // creating a new section 
+            sect = new elfpp::section(*m_generator, elfpp::SHT_PROGBITS);
+
+            sect->set_name(std::string(cur_vobj->name));
+            sect->set_flags(elfpp::SHF_ALLOC | elfpp::SHF_WRITE);
+            sect->set_size(blob_size);  //do the malloc for the get_content fonction
+
+            assert(sect->get_content());//check allocation
+
+            if (!filePath.compare(m_path)) {   //local blob: map_info
+                //memcpy(sect->get_content(), m_data, sect->get_size());
+                /* this way the modification of the elf size are propageted to the giet */
+                sect->set_content(this->m_data);
+            }
+            else
+            {
+                load_bin(filePath, sect->get_content());
+            }
+
+
+            if (blob_size > cur_vobj->length)
+            {
+                std::cout << std::hex << "!!! Warning, specified blob type vobj ("<<
+                cur_vobj->name  <<") size is "<< cur_vobj->length << ", the actual size is "
+                << blob_size  << " !!!" <<std::endl;
+                assert(0 and "blob vobj length smaller than the actual content" );//???
+            }
+
+            cur_vobj->length = blob_size; //set the true size of this BLOB vobj
+
+            vSO->m_file = filePath;
+            vSO->m_loadable = true;
+        }
+        else if (cur_vobj->type == VOBJ_TYPE_ELF)
+        {
+            if (!first)
+                throw exception::RunTimeError(std::string("elf vobj type, must be placed first in a vseg"));
+
+            size_t elf_size;
+            std::string filePath(m_pathHandler.getFullPath(std::string(cur_vobj->binpath)));
+#ifdef MOVER_DEBUG
+            std::cout << "Handling: " << filePath << " ..." << std::endl;
+            std::cout << "Found an ELF vseg" << std::endl;
+#endif
+            if (m_loaders.count(filePath) == 0)
+                m_loaders[filePath] = new elfpp::object(filePath);
+            elfpp::object * loader = m_loaders[filePath]; //TODO:free!?
+
+            sect =  new elfpp::section(*get_sect_by_addr(loader, cur_vaddr)); //copy: for the case we replicate the code
+            if (!sect)
+            {
+                std::cerr << "No section found for " << cur_vobj->name << " at "<< cur_vaddr << std::endl;
+                exit(-1);
+            }
+
+            sect->set_name(std::string(cur_vobj->name));
+
+
+            elf_size = sect->get_size();
+            assert((elf_size > 0) and "ELF section empty ?");
+
+            if (!m_ginit)
+            {
+                /** Initailising the header of the generator from the first binary,
+                ** we suppose that the header is the same for all the binarys **/
+                m_generator->copy_info(*loader, 64);
+                m_ginit = true;
+            }
+
+            if (elf_size > cur_vobj->length)
+            {
+                std::cout << "Warning, specified elf type vobj (" <<
+                cur_vobj->name  << ") size is " << cur_vobj->length << ", the actual size is "
+                << elf_size  << std::endl;
+                assert((0) and "elf vobj length smaller than the actual content");
+            }
+
+            cur_vobj->length = elf_size;//set the true size of this ELF vobj
+
+            vSO->m_file = filePath;
+            vSO->m_loadable = true;
+        }
+
+        //aligning the vobj->paddr if necessary
+        if (cur_vobj->align)
+        {
+            cur_length = PSeg::align(cur_length, cur_vobj->align);
+            aligned = true;
+        }
+
+        cur_vaddr += cur_vobj->length;
+        cur_length += cur_vobj->length;
+        first = false;
+    }
+
+    assert(cur_vaddr >= vseg->vbase);
+
+    vSO->m_length = cur_length; //pageAlign is done by the psegs
+    vSO->m_ident = vseg->ident;
+    vSO->m_align = vobj[vseg->vobj_offset].align;
+
+    //set the lma for vseg that are not peripherals
+    if (ps->type() != PSEG_TYPE_PERI)
+    {
+        if (vseg->ident != 0) ps->addIdent(*vSO);
+        else                  ps->add(*vSO);
+    }
+
+    if (!sect) return;
+
+#ifdef MOVER_DEBUG
+    std::cout << "section: "<< *sect <<"\n seted to: " << (*vSO) << std::endl;
+#endif
+
+    sect->set_vaddr((*vSO).lma());
+    m_generator->add_section(*sect);
+
+} // end vseg_map()
+ 
+
+///////////////////////////////
+void MeMo::buildMap(void * desc)
+{
+    mapping_header_t * header  = (mapping_header_t *) desc;  
+
+    mapping_cluster_t * cluster = get_cluster_base(header);     
+    mapping_vspace_t *  vspace  = get_vspace_base(header);     
+    mapping_pseg_t *    pseg    = get_pseg_base(header); 
+    mapping_vseg_t *    vseg    = get_vseg_base(header);
+
+    // get the psegs
+
+#ifdef MOVER_DEBUG
+    std::cout << "\n******* Storing Pseg information *********\n" << std::endl;
+#endif
+
+    for (size_t cluster_id = 0; cluster_id < header->clusters; cluster_id++) {
+        for (size_t pseg_id = cluster[cluster_id].pseg_offset;
+              pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs;
+              pseg_id++) {
+            std::string name(pseg[pseg_id].name);
+            PSeg *ps = new PSeg(name, 
+                                pseg[pseg_id].base, 
+                                pseg[pseg_id].length, 
+                                pseg[pseg_id].type);
+            m_psegh.m_pSegs.push_back(*ps);
+        }
+    }
+
+    // map global vsegs
+
+#ifdef MOVER_DEBUG
+    std::cout << "\n******* mapping global vsegs *********\n" << std::endl;
+#endif
+
+    // Mapping identity segments first
+    for (size_t vseg_id = 0; vseg_id < header->globals; vseg_id++) {
+        if (vseg[vseg_id].ident == 1) {
+            vseg_map(&vseg[vseg_id]);
+        }
+    }
+
+    // Mapping non-identity segments second
+    for (size_t vseg_id = 0; vseg_id < header->globals; vseg_id++) {
+        if (vseg[vseg_id].ident == 0) {
+            vseg_map(&vseg[vseg_id]);
+        }
+    }
+
+
+
+    // loop on virtual spaces to map private vsegs
+    for (size_t vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {
+#ifdef MOVER_DEBUG
+        std::cout << "\n******* mapping all vsegs of " << vspace[vspace_id].name << " *********\n" << std::endl;
+#endif
+        for (size_t vseg_id = vspace[vspace_id].vseg_offset; 
+             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 
+             vseg_id++) {
+            if (vseg[vseg_id].ident == 1) {
+                vseg_map(&vseg[vseg_id]); 
+            }
+        }
+ 
+        for (size_t vseg_id = vspace[vspace_id].vseg_offset; 
+             vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 
+             vseg_id++) {
+            if (vseg[vseg_id].ident == 0) {
+                vseg_map(&vseg[vseg_id]); 
+            }
+        }
+    } 
+} // end buildMap()
+
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/memo/src/path_handler.cpp
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/path_handler.cpp	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/path_handler.cpp	(revision 283)
@@ -0,0 +1,81 @@
+/* -*- c++ -*-
+ *TODO
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, SoC
+ *         Mohamed Lamine Karaoui <Mohamed.Karaoui@lip6.fr>, 2012
+ */
+
+#include "path_handler.h"
+    
+PathHandler::PathHandler(const std::string& filepath)
+                        :delim('/')
+{
+   dirPath = getFilePath(filepath);
+}
+    
+std::string PathHandler::getFullPath(const std::string& filepath) const
+{
+    return dirPath+filepath;
+}
+
+std::vector<std::string>& PathHandler::split(const std::string &s, char delim, std::vector<std::string> &elems)
+{
+    std::stringstream ss(s);
+    std::string item;
+    while(std::getline(ss, item, delim)) 
+    {
+        elems.push_back(item);
+    }
+    return elems;
+}
+
+
+std::vector<std::string> PathHandler::split(const std::string &s, char delim) 
+{
+    std::vector<std::string> elems;
+    return split(s, delim, elems);
+}
+
+
+std::string PathHandler::getFilePath(const std::string& filepath)
+{
+    std::string path;
+
+    std::vector<std::string> vst= split(filepath, delim);
+
+    if(vst.size() < 2)
+        return "";
+
+    for (unsigned i=0; i<(vst.size()-1); i++)
+        path+= vst.at(i);
+
+    return path+'/';
+}
+
+std::string PathHandler::getFileName(const std::string& filepath)
+{
+
+    std::vector<std::string> vst= split(filepath, delim);
+
+    return vst.back();
+}
+    
+PathHandler::~PathHandler()
+{
+}
Index: /branch/giet_vm_ioc_drivers/memo/src/pseg.cpp
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/pseg.cpp	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/pseg.cpp	(revision 283)
@@ -0,0 +1,428 @@
+/* -*- c++ -*-
+ *
+ * GIET_VM_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * GIET_VM_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, SoC
+ *         Mohamed Lamine Karaoui <Mohamed.Karaoui@lip6.fr>, 2012
+ */
+
+#include <algorithm>
+#include <string.h>
+#include <cassert>
+#include <cstring>
+#include <stdexcept>
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+#include <cstdio>
+
+#include "pseg.h"
+#include "exception.h"
+
+
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+
+
+/*
+ * VSeg
+ */
+
+//////////////////////////////////////
+const std::string & VSeg::name() const {
+	return m_name;
+}
+
+//////////////////////////////////////
+const std::string & VSeg::file() const {
+	return m_file;
+}
+
+///////////////////////////
+uintptr_t VSeg::vma() const {
+	return m_vma;
+}
+
+/////////////////////////
+paddr_t VSeg::lma() const {
+	return m_lma;
+}
+
+///////////////////////////
+size_t VSeg::length() const {
+	return m_length;
+}
+
+/////////////////////////
+size_t VSeg::type() const {
+	return m_type;
+}
+
+/////////////////////////////////////////
+void VSeg::print(std::ostream &o) const
+{
+	o << std::hex << std::noshowbase 
+      << "<Virtual segment from(vaddr): 0x" 
+      << std::setw (8) << std::setfill('0') 
+      << m_vma << ", to(paddr) 0x"
+      << std::setw (16) << std::setfill('0') 
+      << m_lma << ", size: 0x"
+      << std::setw (8) << std::setfill('0') 
+          << m_length  << ",ident: " 
+          << (m_ident ? "yes" : "no") << ", in(file): "
+          << m_file << ", name: " << m_name << ">";
+}
+
+/////////////
+VSeg::~VSeg() {}
+
+/////////////////////////////////////////
+VSeg & VSeg::operator=(const VSeg & ref)
+{
+    if (&ref == this)
+        return *this;
+
+    m_name = ref.m_name;
+    m_file = ref.m_file;
+    m_vma = ref.m_vma;
+    m_lma = ref.m_lma;
+    m_length = ref.m_length;
+    m_ident = ref.m_ident;
+    return *this;
+}
+
+////////////
+VSeg::VSeg()
+    : m_name("No Name"),
+    m_file("Empty section"),
+    m_vma(0),
+    m_length(0),
+    m_loadable(false),
+    m_ident(0)
+{
+}
+
+////////////////////////////////////
+VSeg::VSeg(std::string&  binaryName, 
+        std::string&  name, 
+        uintptr_t     vma, 
+        size_t        length, 
+        bool          loadable, 
+        bool          ident)
+: m_name(name),
+    m_file(binaryName),
+    m_vma(vma),
+    m_length(length),
+    m_loadable(loadable),
+    m_ident(ident)
+{
+}
+
+/////////////////////////////
+VSeg::VSeg(const VSeg &ref):
+    m_name(ref.m_name),
+    m_file(ref.m_file),
+    m_vma(ref.m_vma),
+    m_length(ref.m_length),
+    m_loadable(ref.m_loadable),
+    m_ident(ref.m_ident)
+{
+    (*this) = ref;
+}
+
+
+/*
+ * PSeg
+ */
+
+/////////////////////////
+paddr_t PSeg::lma() const {
+    return m_lma;
+}
+
+///////////////////////////
+paddr_t PSeg::length() const {
+    return m_length;
+}
+
+/////////////////////////
+size_t PSeg::type() const {
+    return m_type;
+}
+
+//////////////////////////////////////
+const std::string & PSeg::name() const {
+    return m_name;
+}
+
+//////////////////////// initialisation used[][] ??? (AG)
+void PSeg::check() const
+{
+
+    if (this->m_type == PSEG_TYPE_PERI)
+        return;
+
+    std::vector<VSeg>::const_iterator it;
+    size_t    size = m_vsegs.size();
+    paddr_t   used[size][2];          // lma, lma+length
+    size_t    i, j, error = 0;
+
+    for (it = m_vsegs.begin(), i = 0; it < m_vsegs.end(); it++, i++)
+    {
+        paddr_t it_limit = (*it).lma() + (*it).length();
+        for(j = 0; j < i; j++)
+        {
+            if (used[j][0] == (*it).lma()) //not the same lma ,
+                {
+                    error = 1;
+                }
+            if (used[j][1] == it_limit)  // and not the same limit
+            {
+                error = 2;
+            }
+            if ((used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1])) // lma  within
+            {
+                error = 3;
+            }
+            if (((used[j][0] < it_limit) and (it_limit < used[j][1]))) // limit no within
+            {
+                error = 4;
+                std::cout << "base: " << std::hex << (*it).lma() << std::endl;
+                std::cout << "limit: " << std::hex << it_limit << std::endl;
+                std::cout << "used[j][0]: " << std::hex << used[j][0] << std::endl;
+                std::cout << "used[j][1]: " << std::hex << used[j][1] << std::endl;
+            }
+            if (error)
+            {
+                std::ostringstream err;
+                err << " Error" << error << ", ovelapping Buffers:" << std::endl 
+                    << *it << std::endl << m_vsegs[j] << std::endl; 
+                throw exception::RunTimeError( err.str().c_str() );
+            }
+
+        }
+        used[i][0] = (*it).lma();
+        used[i][1] = it_limit;
+    }
+}
+
+
+/////////////////////////////////////////////////////////
+paddr_t PSeg::align(paddr_t toAlign, unsigned alignPow2) {
+    return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2; 
+}
+
+//////////////////////////////////////////
+paddr_t PSeg::pageAlign(paddr_t toAlign) {
+    size_t pgs = pageSize();
+    size_t pageSizePow2 = __builtin_ctz(pgs);
+
+    return align(toAlign, pageSizePow2); 
+}
+
+
+
+////////////////////////////
+void PSeg::add(VSeg& vseg) {
+    std::vector<VSeg>::iterator it;
+    int nb_elems = m_vsegs.size();
+    int i = 0;
+    bool mapped = false;
+    paddr_t prev_base = m_lma;
+    paddr_t prev_length = 0x0;
+    paddr_t curr_base = 0x0;
+    paddr_t curr_length = 0x0;
+    paddr_t next_base = 0x0;
+    paddr_t next_length = 0x0;
+
+    const int alignment = max(vseg.m_align, __builtin_ctz(pageSize())); // 12
+
+    if (vseg.length() == 0) {
+        std::cout << "*** Error: Adding a vseg of size 0 (base " << vseg.vma() << ")" << std::endl;
+        exit(1);
+    }
+
+    if (nb_elems == 0) {
+        if (vseg.length() <= m_length) {
+            vseg.m_lma = m_lma;
+            m_vsegs.push_back(vseg);
+            return;
+        }
+        else {
+            std::cout << "*** Error: Not enough space to map first VSeg (base = "
+                      << std::hex << vseg.vma() << " - Size = " << vseg.length() << ")" << std::endl;
+            std::cout << "    PSeg too small! (base = " << m_lma << " - size = "
+                      << m_length << ")" << std::endl;
+            exit(1);
+        }
+    }
+
+    curr_base = m_vsegs[0].lma(); // Initialisation avant recherche du min
+    curr_length = m_vsegs[0].length();
+    for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
+        if ((*it).lma() < curr_base) {
+            curr_base = (*it).lma();
+            curr_length = (*it).length();
+        }
+    }
+
+    while (i < nb_elems) {
+        if (align(prev_base + prev_length, alignment) + vseg.length() <= curr_base) {
+            vseg.m_lma = align(prev_base + prev_length, alignment);
+            mapped = true;
+            break;
+        }
+        else if (i < nb_elems - 1) {
+            // Searching for the vseg already mapped with lowest paddr > curr_base
+            next_base = 0;
+            bool found = false;
+            for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
+                if ((!found || (*it).lma() < next_base) && (*it).lma() > curr_base) {
+                    found = true;
+                    next_base = (*it).lma();
+                    next_length = (*it).length();
+                }
+            }
+            assert(found);
+
+            prev_base = curr_base;
+            prev_length = curr_length;
+
+            curr_base = next_base;
+            curr_length = next_length;
+        }
+        else {
+            if (align(curr_base + curr_length, alignment) + vseg.length() <= m_lma + m_length) {
+                vseg.m_lma = align(curr_base + curr_length, alignment);
+                mapped = true;
+            }
+        }
+        i++;
+    }
+
+    if (!mapped) {
+        std::cout << "*** Error: Not enough space to map VSeg (base = " << std::hex << vseg.vma() << " - Size = " << vseg.length() << ")" << std::endl;
+        exit(1);
+    }
+
+    m_vsegs.push_back(vseg); 
+}
+
+
+/////////////////////////////////
+void PSeg::addIdent(VSeg& vseg) {
+    std::vector<VSeg>::iterator it;
+
+    for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
+        if ((vseg.vma() == (*it).lma()) ||
+            ((vseg.vma() < (*it).lma()) && (vseg.vma() + vseg.length() > (*it).lma())) ||
+            ((vseg.vma() > (*it).lma()) && ((*it).lma() + (*it).length() > vseg.vma()))) {
+            std::cout << "*** Error: Identity VSeg overlaps another segment:" << std::endl
+                      << "Added Segment Base : " << std::hex << vseg.vma()
+                      << " - Size : " << vseg.length() << std::endl;
+            std::cout << "Existing Segment Base : " << (*it).lma()
+                      << " - size : " << (*it).length() << std::endl;
+            exit(1);
+        }
+    }
+
+    vseg.m_lma = vseg.m_vma;
+    m_vsegs.push_back(vseg); 
+}
+
+
+/////////////////////////////////////////
+PSeg & PSeg::operator=(const PSeg &ref) {
+    if (&ref == this) {
+        return *this;
+    }
+
+    m_name = ref.m_name;
+    m_length = ref.m_length;
+    m_lma = ref.m_lma;
+    m_vsegs = ref.m_vsegs;
+    m_type = ref.m_type;
+
+	return *this;
+}
+
+//////////////////////////////////////////
+void PSeg::print(std::ostream &o) const
+{
+	o << "<Physical segment "
+	  << std::showbase << m_name
+	  << ", from: " << std::hex 
+      << m_lma
+      << ", size : "  << m_length 
+      << ", type : "  << m_type 
+      << ", containing: "<< std::endl;
+        std::vector<VSeg>::const_iterator it;
+        for(it = m_vsegs.begin(); it < m_vsegs.end(); it++)
+    o << " " << *it << std::endl;
+
+    o << ">";
+}
+
+////////////////////////////////////
+PSeg::PSeg( const std::string &name,
+            paddr_t           lma,
+            paddr_t           length,
+            size_t            type)
+{
+    m_name = name;
+    m_length = length;
+    m_type = type;
+    m_lma = lma;
+}
+
+////////////////////////////////////
+PSeg::PSeg(const std::string &name):
+      m_lma(0),
+      m_length(0) {
+    m_name = name;
+}
+
+
+////////////////////////////////////
+PSeg::PSeg(const PSeg& pseg) {
+    m_name = pseg.m_name;
+    m_length = pseg.m_length;
+    m_lma = pseg.m_lma;
+    m_vsegs = pseg.m_vsegs;
+    m_type = pseg.m_type;
+
+    (*this) = pseg;
+}
+
+PSeg::~PSeg() {}
+
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/memo/src/pseg_handler.cpp
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/src/pseg_handler.cpp	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/src/pseg_handler.cpp	(revision 283)
@@ -0,0 +1,112 @@
+/* -*- c++ -*-
+ *
+ * GIET_VM_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of GIET_VM, GNU LGPLv2.1.
+ * 
+ * GIET_VM is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * GIET_VM 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GIET_VM; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * GIET_VM_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, SoC
+ *         Mohamed Lamine Karaoui <Mohamed.Karaoui@lip6.fr>, 2012
+ */
+
+#include <algorithm>
+#include <string.h>
+#include <cassert>
+#include <cstring>
+#include <stdexcept>
+
+#include <iostream>
+#include <iomanip>
+
+#include "pseg_handler.h"
+#include "exception.h"
+
+/*
+ * PSegHandler
+ */
+
+/////////////////////////////////////
+PSeg& PSegHandler::get( size_t pos  )
+{
+    try
+    {
+        return m_pSegs.at( pos );
+
+    }catch (std::out_of_range& oor) {
+        std::cerr << "PSeg "<< pos <<"(id) is missing" << std::endl;
+    }
+    exit(1);
+}
+
+//////////////////////////////////////////////////////////////
+const PSeg& PSegHandler::getByAddr(uintptr_t segAddress) const
+{
+    std::vector<PSeg>::const_iterator it ;
+    for(it = m_pSegs.begin(); it < m_pSegs.end(); it++)
+    {
+        paddr_t lma = (*it).lma();
+        if( lma == segAddress )
+            return *it;
+    }
+
+    std::cerr << "Unfound Physical segment: " 
+              << std::hex << std::showbase 
+              << segAddress << std::endl;
+    exit(1);
+}
+
+///////////////////////////////
+void PSegHandler::check() const
+{
+    std::vector<PSeg>::const_iterator it ;
+    for(it = m_pSegs.begin(); it < m_pSegs.end(); it++)
+    {
+        (*it).check();
+    }
+}
+
+void PSegHandler::print( std::ostream &o ) const
+{
+    o << std::dec ; 
+	o << "< " << m_pSegs.size() <<  " Segments (page size = " << PSeg::pageSize() << ") :"<< std::endl;
+    std::vector<PSeg>::const_iterator it ;
+    for(it = m_pSegs.begin(); it < m_pSegs.end(); it++)
+        o << *it << std::endl;
+    o << ">";
+}
+
+PSegHandler::~PSegHandler()
+{
+//    std::cout << "Deleted PSegHandler " << *this << std::endl;
+}
+
+PSegHandler::PSegHandler()
+{
+    //std::cout << "New empty PSegHandler " << *this << std::endl;
+}
+
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: /branch/giet_vm_ioc_drivers/memo/test/check.sh
===================================================================
--- /branch/giet_vm_ioc_drivers/memo/test/check.sh	(revision 283)
+++ /branch/giet_vm_ioc_drivers/memo/test/check.sh	(revision 283)
@@ -0,0 +1,26 @@
+#! /bin/sh
+
+### Debug
+
+#set -x
+#set -e
+
+### Colors
+
+RED="\033[0;31m"
+GREEN="\033[0;32m"
+WHITE="\033[0;37m"
+
+### Code
+
+#TODO
+
+echo -n "Test 1 : "
+
+./memo.x memo.x 2>test1.stderr 1>test1.stdout
+
+if test "1$?" -eq "10"; then
+    echo -e $GREEN "OK" $WHITE
+else
+    echo -e $RED "KO" $WHITE
+fi
Index: /branch/giet_vm_ioc_drivers/pgcd/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/pgcd/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/pgcd/Makefile	(revision 283)
@@ -0,0 +1,24 @@
+APP_NAME=pgcd
+
+USE+= stdio.o
+
+USES=$(patsubst %,$(BUILD_PATH)/$(LIB_NAME)/%,$(USE))
+
+OBJS= main.o 
+
+all: $(APP_NAME).elf
+
+BIN_NAME_PATH=$(BUILD_PATH)$(APP_NAME).elf
+
+$(APP_NAME).elf: $(OBJS) $(APP_NAME).ld
+	$(LD) -o $(BIN_NAME_PATH) -T $(APP_NAME).ld $(OBJS) $(USES)
+	$(DU) -D $(BIN_NAME_PATH) > $@.txt
+
+%.o: %.c 
+	$(CC)  $(INCLUDE) $(CFLAGS) $($*.o_CFLAGS) -c -o  $@ $<
+	$(DU) -D  $@ >  $@.txt
+
+
+clean:
+	rm -f *.o *.elf *.txt core *~ 2>$(TRASH)
+	rm $(BIN_NAME_PATH) 2>$(TRASH)
Index: /branch/giet_vm_ioc_drivers/pgcd/main.c
===================================================================
--- /branch/giet_vm_ioc_drivers/pgcd/main.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/pgcd/main.c	(revision 283)
@@ -0,0 +1,36 @@
+#include "stdio.h"
+
+/////////////////////////////////////////
+__attribute__ ((constructor)) void main()
+{
+    unsigned int opx;
+    unsigned int opy;
+
+    giet_tty_printf("Starting task PGCD on processor %d at cycle %d\n",
+                   giet_procid(), giet_proctime());
+
+    while (1) 
+    {
+        giet_tty_printf("\n*******************\n");
+        giet_tty_printf("operand X = ");
+        giet_tty_getw( &opx );
+        giet_tty_printf("\n");
+        giet_tty_printf("operand Y = ");
+        giet_tty_getw( &opy );
+        giet_tty_printf("\n");
+        if( (opx == 0) || (opy == 0) ) 
+        {
+           giet_tty_printf("operands must be larger than 0\n");
+        } 
+        else 
+        {
+            while (opx != opy) 
+            {
+                if(opx > opy)   opx = opx - opy;
+                else            opy = opy - opx;
+            }
+            giet_tty_printf("pgcd      = %d\n", opx);
+        }
+    }
+} // end pgcd
+
Index: /branch/giet_vm_ioc_drivers/pgcd/pgcd.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/pgcd/pgcd.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/pgcd/pgcd.ld	(revision 283)
@@ -0,0 +1,39 @@
+/****************************************************************************
+* Definition of the base address for all virtual segments
+*****************************************************************************/
+
+seg_code_base      = 0x00400000;
+seg_data_base      = 0x00500000;	
+
+/***************************************************************************
+* Grouping sections into segments for code and data
+***************************************************************************/
+
+SECTIONS
+{
+    . = seg_code_base;
+    seg_code : 
+    {
+        *(.text)
+    }
+    . = seg_data_base;
+    seg_data : 
+    {
+        *(.ctors)
+        *(.rodata)
+        /* . = ALIGN(4); */
+        *(.rodata.*)
+        /* . = ALIGN(4); */
+        *(.data)
+        /* . = ALIGN(4); */
+        *(.lit8)
+        *(.lit4)
+        *(.sdata)
+        /* . = ALIGN(4); */
+        *(.bss)
+        *(COMMON)
+        *(.sbss)
+        *(.scommon)
+    }
+}
+
Index: /branch/giet_vm_ioc_drivers/router/Makefile
===================================================================
--- /branch/giet_vm_ioc_drivers/router/Makefile	(revision 283)
+++ /branch/giet_vm_ioc_drivers/router/Makefile	(revision 283)
@@ -0,0 +1,24 @@
+APP_NAME=router
+
+USE+= stdio.o
+USE+= mwmr_channel.o
+
+USES=$(patsubst %,$(BUILD_PATH)/$(LIB_NAME)/%,$(USE))
+
+OBJS= main.o 
+
+all: $(APP_NAME).elf
+
+BIN_NAME_PATH=$(BUILD_PATH)$(APP_NAME).elf
+
+$(APP_NAME).elf: $(OBJS) $(APP_NAME).ld
+	$(LD) -o $(BIN_NAME_PATH) -T $(APP_NAME).ld $(OBJS) $(USES)
+	$(DU) -D $(BIN_NAME_PATH) > $@.txt
+
+%.o: %.c 
+	$(CC)  $(INCLUDE) $(CFLAGS) $($*.o_CFLAGS) -c -o  $@ $<
+	$(DU) -D  $@ >  $@.txt
+
+clean:
+	rm -f *.o *.elf *.txt core *~ 2>$(TRASH)
+	rm $(BIN_NAME_PATH) 2>$(TRASH)
Index: /branch/giet_vm_ioc_drivers/router/main.c
===================================================================
--- /branch/giet_vm_ioc_drivers/router/main.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/router/main.c	(revision 283)
@@ -0,0 +1,116 @@
+#include "stdio.h"
+#include "mwmr_channel.h"
+#include "mapping_info.h"
+
+#define NMAX 200
+
+/////////////////////////////////////////////
+__attribute__ ((constructor)) void producer()
+{
+
+    unsigned int 	n;
+    unsigned int 	buf;
+    mwmr_channel_t*	mwmr;
+
+    giet_tty_printf( "*** Starting task producer on processor %d", giet_procid() );
+    giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() );
+
+    if( giet_vobj_get_vbase( "router" , 
+                             "mwmr_in", 
+                             VOBJ_TYPE_MWMR, 
+                             (void*)&mwmr ) )
+    {
+        giet_tty_printf( "\n[ERROR] in producer task :\n");
+        giet_tty_printf( "          undefined <mwmr_in> channel: %d\n", mwmr);
+        giet_tty_printf( "*** &mwmr_in = %x\n\n", (unsigned int)mwmr );
+        giet_exit();
+    }
+
+    // main loop : display token value = source index
+    for(n = 0 ; n < NMAX ; n++) 
+    { 
+        buf = n;
+        mwmr_write( mwmr, &buf , 1 );
+        giet_tty_printf( "transmitted value : %d\n", buf);
+    }
+
+    giet_tty_printf( "\n*** Completing producer task at cycle %d ***\n", giet_proctime());
+    giet_exit();
+
+} // end producer()
+
+/////////////////////////////////////////////
+__attribute__ ((constructor)) void consumer()
+{
+    unsigned int 	n;
+    unsigned int 	buf;
+    mwmr_channel_t*	mwmr;
+
+    giet_tty_printf( "*** Starting task consumer on processor %d", giet_procid() );
+    giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() );
+
+    if ( giet_vobj_get_vbase( "router" , 
+                              "mwmr_out", 
+                              VOBJ_TYPE_MWMR, 
+                              (void*)&mwmr ) )
+    {
+        giet_tty_printf( "\n[ERROR] in consumer task :\n");
+        giet_tty_printf( "          undefined <mwmr_out> channel\n");
+        giet_exit();
+    }
+
+    // main loop : display token arrival index and value
+    for(n = 0 ; n < NMAX ; n++ ) 
+    { 
+        mwmr_read( mwmr, &buf , 1 );
+        giet_tty_printf( "received token %d / value = %d\n", n  , buf);
+    }
+
+    giet_tty_printf( "\n*** Completing consumer task at cycle %d ***\n", giet_proctime());
+    giet_exit();
+
+} // end consumer()
+
+///////////////////////////////////////////
+__attribute__ ((constructor)) void router()
+{
+    unsigned int 	buf;
+    unsigned int 	x;
+    unsigned int	tempo;
+    mwmr_channel_t*	mwmr_in ;
+    mwmr_channel_t* mwmr_out ;
+
+    
+    giet_tty_printf( "*** Starting task router on processor %d", giet_procid() ); 
+    giet_tty_printf( " at cycle %d ***\n\n", giet_proctime() );
+
+    if ( giet_vobj_get_vbase( "router" , 
+                              "mwmr_out", 
+                              VOBJ_TYPE_MWMR, 
+                              (void*)&mwmr_out ) )
+    {
+        giet_tty_printf( "\n[ERROR] in router task :\n");
+        giet_tty_printf( "          undefined <mwmr_in> channel\n");
+        giet_exit();
+    }
+
+    if (  giet_vobj_get_vbase( "router" , 
+                               "mwmr_in", 
+                               VOBJ_TYPE_MWMR, 
+                               (void*)&mwmr_in ) )
+    {
+        giet_tty_printf( "\n[ERROR] in router task :\n");
+        giet_tty_printf( "          undefined <mwmr_out> channel\n");
+        giet_exit();
+    }
+
+    // main loop
+    while(1)
+    {
+        mwmr_read( mwmr_in , &buf , 1 );
+        tempo = giet_rand() >> 6;
+        for ( x = 0 ; x < tempo ; x++ ) asm volatile ("");
+        giet_tty_printf( "token value : %d / temporisation = %d\n", buf, tempo);
+        mwmr_write( mwmr_out, &buf , 1 );
+    }
+}
Index: /branch/giet_vm_ioc_drivers/router/router.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/router/router.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/router/router.ld	(revision 283)
@@ -0,0 +1,39 @@
+/****************************************************************************
+* Definition of the base address for all virtual segments
+*****************************************************************************/
+
+seg_code_base      = 0x00400000;
+seg_data_base      = 0x00500000;
+
+/***************************************************************************
+* Grouping sections into segments for code and data
+***************************************************************************/
+
+SECTIONS
+{
+    . = seg_code_base;
+    seg_code : 
+    {
+        *(.text)
+    }
+    . = seg_data_base;
+    seg_data : 
+    {
+        *(.ctors)
+        *(.rodata)
+        /* . = ALIGN(4); */
+        *(.rodata.*)
+        /* . = ALIGN(4); */
+        *(.data)
+        /* . = ALIGN(4); */
+        *(.lit8)
+        *(.lit4)
+        *(.sdata)
+        /* . = ALIGN(4); */
+        *(.bss)
+        *(COMMON)
+        *(.sbss)
+        *(.scommon)
+    }
+}
+
Index: /branch/giet_vm_ioc_drivers/sort/main.c
===================================================================
--- /branch/giet_vm_ioc_drivers/sort/main.c	(revision 283)
+++ /branch/giet_vm_ioc_drivers/sort/main.c	(revision 283)
@@ -0,0 +1,272 @@
+///////////////////////////////////////////////////////////////////////////////
+// File :
+//      
+//      main.c
+//
+// Date :
+//      
+//      November 2013
+//
+// Author :
+//
+//      Cesar Fuguet Tortolero <cesar.fuguet-tortolero@lip6.fr>
+//
+// Description :
+//
+//      Sort application using the GIET-VM OS. This application uses the
+//      barrier routines to apply a sort algorithm in several stages.
+//
+//      Considerations :
+//
+//          - It supports up to 256 processors and the number of processors
+//            must be a power of 2.
+//
+//          - If there is only one TTY available, this application uses a spin
+//            lock to avoid several threads writting at the same time.
+//
+//          - This application must be executed on a cache coherent
+//            architecture. Otherwise some modifications must be applied
+//
+//          - The processors executing this application must have a contiguous
+//            processor id and the first processor must have id 0.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "stdio.h"
+#include "hard_config.h"
+#include "barrier.h"
+
+//////////////////////////////////////////////////////////////////////////
+// The NTHREADS constant must be modified depending on the desired number of
+// threads
+
+#define NTHREADS        8
+#define ARRAY_LENGTH    (NTHREADS * 128)
+#define IPT             (ARRAY_LENGTH / NTHREADS) // ITEMS PER THREAD
+
+////////////////////////////////////////////////////////////////////////////////
+// Processors other than 0 display algorithm state
+// The processor 0 always displays some information so this does not affect him 
+
+#define VERBOSE         1
+
+///////////////////////////////////////////////////////////////////////
+// Define printf according to verbosity option and number of available
+// TTY
+
+#if (VERBOSE == 1)
+#   define printf(...)     giet_tty_printf(__VA_ARGS__)
+#   define puts(...)       giet_tty_puts(__VA_ARGS__)
+#else       // VERBOSE == 0
+#   define printf(...)
+#   define puts(...)
+#endif
+
+#define task0_printf(...) if(thread_id == 0) giet_tty_printf(__VA_ARGS__)
+
+#define exit    giet_exit
+#define procid  giet_procid
+#define rand    giet_rand
+
+int array0[ARRAY_LENGTH];
+int array1[ARRAY_LENGTH];
+
+volatile int init_ok = 0;
+
+void bubbleSort(
+        int * array,
+        unsigned int length,
+        unsigned int init_pos);
+
+void merge(
+        int * array,
+        int * result,
+        int length,
+        int init_pos_a,
+        int init_pos_b,
+        int init_pos_result);
+
+///////////////////////////////////////////////////
+// This application support at most 256 processors
+// Number of barriers = log2(NTHREADS)
+
+giet_barrier_t barrier[8];
+
+__attribute__ ((constructor)) void sort()
+{
+    int thread_id = giet_thread_id();
+
+    int * src_array;
+    int * dst_array;
+    int i;
+
+    printf("[ Thread %d ] Initializing vector and barriers...\n\r", thread_id);
+
+    ///////////////////////////
+    // Barriers Initialization
+
+    for (i = 0; i < __builtin_ctz(NTHREADS); i++)
+    {
+        barrier_init(&barrier[i], NTHREADS >> i);
+    }
+
+    ////////////////////////
+    // Array Initialization
+
+    for (i = IPT * thread_id; i < IPT * (thread_id + 1); i++)
+    {
+        array0[i] = rand();
+    }
+
+    ///////////////////////////////////
+    // Parallel sort of array elements
+
+    printf("[ Thread %d ] Stage 0: Processor Sorting...\n\r", thread_id);
+
+    bubbleSort(array0, IPT, IPT * thread_id);
+
+    printf("[ Thread %d ] Finishing Stage 0\n\r", thread_id);
+
+    for (i = 0; i < __builtin_ctz(NTHREADS); i++)
+    {
+        asm volatile ("sync");
+        barrier_wait(&barrier[i]);
+
+        if((thread_id % (2 << i)) != 0)
+        {
+            printf("[ Thread %d ] Quits\n\r", thread_id);
+            exit();
+        }
+
+        printf("[ Thread %d ] Stage %d: Starting...\n\r", thread_id, i+1);
+
+        if((i % 2) == 0)
+        {
+            src_array = &array0[0];
+            dst_array = &array1[0];
+        }
+        else
+        {
+            src_array = &array1[0];
+            dst_array = &array0[0];
+        }
+
+        merge(src_array, dst_array
+                , IPT << i
+                , IPT * thread_id
+                , IPT * (thread_id + (1 << i))
+                , IPT * thread_id
+                );
+
+        printf("[ Thread %d ] Finishing Stage %d\n\r", thread_id, i + 1);
+    }
+
+    int success;
+    int failure_index;
+
+    //////////////////////////////
+    // Verify the resulting array
+
+    if(thread_id == 0)
+    {
+        success = 1;
+
+        for(i=0; i<(ARRAY_LENGTH-1); i++)
+        {
+            if(dst_array[i] > dst_array[i+1])
+            {
+
+                success = 0;
+                failure_index = i;
+                break;
+            }
+        }
+
+        if (success)
+        {
+            printf("[ Thread 0 ] Success!!\n\r");
+        }
+        else
+        {
+            printf("[ Thread 0 ] Failure!! Incorrect element: %d\n\r", failure_index);
+
+
+            for(i=0; i<ARRAY_LENGTH; i++)
+            {
+                printf("array[%d] = %d\n", i, dst_array[i]);
+            }
+        }
+    }
+
+    exit();
+}
+
+void bubbleSort(
+        int * array,
+        unsigned int length,
+        unsigned int init_pos)
+{
+    int i;
+    int j;
+    int aux;
+
+    for(i = 0; i < length; i++)
+    {
+        for(j = init_pos; j < (init_pos + length - i - 1); j++)
+        {
+            if(array[j] > array[j + 1])
+            {
+                aux          = array[j + 1];
+                array[j + 1] = array[j];
+                array[j]     = aux;
+            }
+        }
+    }
+}
+
+void merge(
+        int * array,
+        int * result,
+        int length,
+        int init_pos_a,
+        int init_pos_b,
+        int init_pos_result)
+{
+    int i;
+    int j;
+    int k;
+
+    i = 0;
+    j = 0;
+    k = init_pos_result;
+
+    while((i < length) || (j < length))
+    {
+        if((i < length) && (j < length))
+        {
+            if(array[init_pos_a + i] < array[init_pos_b + j])
+            {
+                result[k++] = array[init_pos_a + i];
+                i++;
+            }
+            else
+            {
+                result[k++] = array[init_pos_b + j];
+                j++;
+            }
+        }
+        else if(i < length)
+        {
+            result[k++] = array[init_pos_a + i];
+            i++;
+        }
+        else
+        {
+            result[k++] = array[init_pos_b + j];
+            j++;
+        }
+    }
+}
+
+/* vim: tabstop=4 : shiftwidth=4 : expandtab
+*/
Index: /branch/giet_vm_ioc_drivers/sort/sort.ld
===================================================================
--- /branch/giet_vm_ioc_drivers/sort/sort.ld	(revision 283)
+++ /branch/giet_vm_ioc_drivers/sort/sort.ld	(revision 283)
@@ -0,0 +1,40 @@
+/****************************************************************************
+* Definition of the base address for all virtual segments
+*****************************************************************************/
+
+seg_code_base      = 0x00400000;
+seg_data_base      = 0x00500000;
+
+/***************************************************************************
+* Grouping sections into segments for code and data
+***************************************************************************/
+
+SECTIONS
+{
+    . = seg_code_base;
+    seg_code : 
+    {
+        *(.text)
+        *(.text.*)
+    }
+    . = seg_data_base;
+    seg_data : 
+    {
+        *(.ctors)
+        *(.rodata)
+        /* . = ALIGN(4); */
+        *(.rodata.*)
+        /* . = ALIGN(4); */
+        *(.data)
+        /* . = ALIGN(4); */
+        *(.lit8)
+        *(.lit4)
+        *(.sdata)
+        /* . = ALIGN(4); */
+        *(.bss)
+        *(COMMON)
+        *(.sbss)
+        *(.scommon)
+    }
+}
+
