diff --git a/ecosflash/Makefile b/ecosflash/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..dfff37c2e1fb8cd6e5512cec98c1511735825cb9
--- /dev/null
+++ b/ecosflash/Makefile
@@ -0,0 +1,11 @@
+# Create OpenOCD eCos flash driver
+# Syntax: make INSTALL_DIR=ecosinstalldir OUTPUT=outputname
+
+include $(INSTALL_DIR)/include/pkgconf/ecos.mak
+
+all:
+	$(ECOS_COMMAND_PREFIX)gcc $(ECOS_GLOBAL_CFLAGS) $(ECOS_GLOBAL_LDFLAGS) -g -o debug_$(OUTPUT).elf -nostdlib  flash.S flash.c -Wl,--gc-sections -I$(INSTALL_DIR)/include -Wl,$(INSTALL_DIR)/lib/libtarget.a -Wl,-Map,flash.map   
+	cp debug_$(OUTPUT).elf $(OUTPUT).elf
+	$(ECOS_COMMAND_PREFIX)strip $(OUTPUT).elf
+	echo Flash driver $(OUTPUT).elf
+
diff --git a/ecosflash/at91eb40a.elf b/ecosflash/at91eb40a.elf
new file mode 100644
index 0000000000000000000000000000000000000000..451657a5a506ab1f60981b8b3627288c8950bc8f
Binary files /dev/null and b/ecosflash/at91eb40a.elf differ
diff --git a/ecosflash/debug_at91eb40a.elf b/ecosflash/debug_at91eb40a.elf
new file mode 100644
index 0000000000000000000000000000000000000000..0bada05a877466fe8ece89e4f2937458491ccb1d
Binary files /dev/null and b/ecosflash/debug_at91eb40a.elf differ
diff --git a/ecosflash/flash.S b/ecosflash/flash.S
new file mode 100644
index 0000000000000000000000000000000000000000..dc30d1633173d9c41aa7b93aef553700a4002e18
--- /dev/null
+++ b/ecosflash/flash.S
@@ -0,0 +1,58 @@
+/*
+	Jump table for flash driver
+	
+	Registers in ARM callling convention is to place args in registers 
+	starting at r0.
+	
+	So for:
+	
+	void foo(int a, int b, int c).
+	
+	a=r0
+	b=r1
+	c=r2
+	
+	
+*/
+	.global _stack_base
+	.global _stack_start
+	.global _workarea
+	.global _start
+	.global _start_bss_clear
+_start:
+	// offset=0
+	// int erase(void *address, int len)
+	ldr     sp,=_stack_start                
+	bl erase
+	nop // Stop CPU here using hw breakpoint
+	
+	// offset=0xc
+	// int program(void *buffer, void *address, int len)	
+	ldr     sp,=_stack_start              
+	bl program
+	nop // Stop CPU here using hw breakpoint
+	
+	// offset=0x18
+	ldr     r0,=_workarea                
+	nop // Stop CPU here using hw breakpoint
+	
+	// offset=0x20
+	// int init() - returns error message if the flash chip can't be detected	
+	ldr     sp,=_stack_start              
+	bl init
+	nop // Stop CPU here using hw breakpoint
+
+    .section ".bss"
+    .balign 4
+_stack_base:
+        .rept 4096
+        .byte 0
+        .endr
+_stack_start:
+    .balign 4
+_workarea:
+        .rept 8192
+        .byte 0
+        .endr
+	// NB!!! we clear bss while the stack is in use, so we start BSS clearing here !!! :-)
+_start_bss_clear:
diff --git a/ecosflash/flash.c b/ecosflash/flash.c
new file mode 100644
index 0000000000000000000000000000000000000000..654273d30d25a9eaa2fbb2c36fda66c91956a919
--- /dev/null
+++ b/ecosflash/flash.c
@@ -0,0 +1,72 @@
+#include <string.h>
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+
+
+int myprintf(char *format, ...)
+{
+  return 0;
+}
+
+extern char _start_bss_clear;
+extern char __bss_end__;
+
+int init()
+{
+	// set up runtime environment
+	char *t;
+	for (t=&_start_bss_clear; t<&__bss_end__; t++)
+	{
+		*t=0;
+	}
+	return flash_init((_printf *)&myprintf);
+	
+}
+
+
+int checkFlash(void *addr, int len)
+{
+    // Return error for illegal addresses
+    if ((addr<flash_info.start)||(addr>flash_info.end))
+    	return FLASH_ERR_INVALID;
+    if ((((cyg_uint8 *)addr)+len)>(cyg_uint8 *)flash_info.end)
+    	return FLASH_ERR_INVALID;
+    return FLASH_ERR_OK;
+}
+
+
+int erase(void *address, int len)	
+{
+	int retval;
+	void *failAddress;
+	
+	retval=checkFlash(address, len);
+	if (retval!=0)
+		return retval;
+	
+	retval=init();
+	if (retval!=0)
+		return retval;
+	return flash_erase(address, len, &failAddress);
+}
+
+
+
+extern char _end;
+
+// Data follows immediately after program, long word aligned.
+int program(void *buffer, void *address, int len)	
+{
+	int retval;
+	void *failAddress;
+	retval=checkFlash(address, len);
+	if (retval!=0)
+		return retval;
+	
+	retval=init();
+	if (retval!=0)
+		return retval;
+	//int flash_program(void *_addr, void *_data, int len, void **err_addr)
+	return flash_program(address, buffer, len, &failAddress);
+}
diff --git a/ecosflash/flash.map b/ecosflash/flash.map
new file mode 100644
index 0000000000000000000000000000000000000000..d47258b7eda47f0a72065e64a5e7aa2bd3b7afaf
--- /dev/null
+++ b/ecosflash/flash.map
@@ -0,0 +1,390 @@
+Archive member included because of file (symbol)
+
+/tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+                              /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o (flash_init)
+/tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+                              /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o) (flash_hwr_init)
+/tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+                              /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o) (memcpy)
+/tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+                              /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o) (memcmp)
+
+Memory Configuration
+
+Name             Origin             Length             Attributes
+*default*        0x00000000         0xffffffff
+
+Linker script and memory map
+
+LOAD /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/cccPBW5f.o
+LOAD /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+LOAD /tmp/ecosboard/ecos/install/lib/libtarget.a
+                0x00008000                PROVIDE (__executable_start, 0x8000)
+                0x00008000                . = 0x8000
+
+.interp
+ *(.interp)
+
+.hash
+ *(.hash)
+
+.dynsym
+ *(.dynsym)
+
+.dynstr
+ *(.dynstr)
+
+.gnu.version
+ *(.gnu.version)
+
+.gnu.version_d
+ *(.gnu.version_d)
+
+.gnu.version_r
+ *(.gnu.version_r)
+
+.rel.dyn
+ *(.rel.init)
+ *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+ *(.rel.fini)
+ *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+ *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+ *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+ *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+ *(.rel.ctors)
+ *(.rel.dtors)
+ *(.rel.got)
+ *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+
+.rela.dyn
+ *(.rela.init)
+ *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+ *(.rela.fini)
+ *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+ *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+ *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+ *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+ *(.rela.ctors)
+ *(.rela.dtors)
+ *(.rela.got)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+
+.rel.plt
+ *(.rel.plt)
+
+.rela.plt
+ *(.rela.plt)
+
+.init
+ *(.init)
+
+.plt
+ *(.plt)
+
+.text           0x00008000      0x6f8
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ .text          0x00008000       0x34 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/cccPBW5f.o
+                0x00008000                _start
+ .text.myprintf
+                0x00008034       0x10 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+                0x00008034                myprintf
+ .text.init     0x00008044       0x50 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+                0x00008044                init
+ .text.erase    0x00008094       0xc0 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+                0x00008094                erase
+ .text.program  0x00008154       0xc8 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+                0x00008154                program
+ .text.flash_init
+                0x0000821c       0x6c /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+                0x0000821c                flash_init
+ .text.flash_dev_query
+                0x00008288       0x20 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+                0x00008288                flash_dev_query
+ .text.flash_erase
+                0x000082a8      0x140 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+                0x000082a8                flash_erase
+ .text.flash_program
+                0x000083e8      0x154 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+                0x000083e8                flash_program
+ .text.flash_hwr_init
+                0x0000853c       0xa4 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+                0x0000853c                flash_hwr_init
+ .text.flash_hwr_map_error
+                0x000085e0        0x4 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+                0x000085e0                flash_hwr_map_error
+ .text.__memcmp
+                0x000085e4      0x114 /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+                0x000085e4                memcmp
+                0x000085e4                __memcmp
+ *(.gnu.warning)
+ *(.glue_7t)
+ *(.glue_7)
+
+.2ram.flash_query
+                0x000086f8       0x54
+ .2ram.flash_query
+                0x000086f8       0x54 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+                0x000086f8                flash_query
+
+.2ram.flash_erase_block
+                0x0000874c      0x230
+ .2ram.flash_erase_block
+                0x0000874c      0x230 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+                0x0000874c                flash_erase_block
+
+.2ram.flash_program_buf
+                0x0000897c       0xe8
+ .2ram.flash_program_buf
+                0x0000897c       0xe8 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+                0x0000897c                flash_program_buf
+
+.fini
+ *(.fini)
+                0x00008a64                PROVIDE (__etext, .)
+                0x00008a64                PROVIDE (_etext, .)
+                0x00008a64                PROVIDE (etext, .)
+
+.rodata         0x00008a64      0x318
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ .rodata.str1.4
+                0x00008a64      0x1fb /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+                                0x1fc (size before relaxing)
+ *fill*         0x00008c5f        0x1 00
+ .rodata.supported_devices
+                0x00008c60      0x11c /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+
+.rodata1
+ *(.rodata1)
+
+.eh_frame_hdr
+ *(.eh_frame_hdr)
+                0x00008e7c                . = (ALIGN (0x100) + (. & 0xff))
+                0x00008e7c                . = ALIGN (0x4)
+                0x00008e7c                PROVIDE (__preinit_array_start, .)
+
+.preinit_array
+ *(.preinit_array)
+                0x00008e7c                PROVIDE (__preinit_array_end, .)
+                0x00008e7c                PROVIDE (__init_array_start, .)
+
+.init_array
+ *(.init_array)
+                0x00008e7c                PROVIDE (__init_array_end, .)
+                0x00008e7c                PROVIDE (__fini_array_start, .)
+
+.fini_array
+ *(.fini_array)
+                0x00008e7c                PROVIDE (__fini_array_end, .)
+
+.data           0x00008e7c        0x0
+                0x00008e7c                __data_start = .
+ *(.data .data.* .gnu.linkonce.d.*)
+
+.data1
+ *(.data1)
+
+.tdata
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+
+.tbss
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon)
+
+.eh_frame
+ *(.eh_frame)
+
+.gcc_except_table
+ *(.gcc_except_table)
+
+.dynamic
+ *(.dynamic)
+
+.ctors
+ *crtbegin*.o(.ctors)
+ *(EXCLUDE_FILE(*crtend*.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+
+.dtors
+ *crtbegin*.o(.dtors)
+ *(EXCLUDE_FILE(*crtend*.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+
+.jcr
+ *(.jcr)
+
+.got
+ *(.got.plt)
+ *(.got)
+                0x00008e7c                _edata = .
+                0x00008e7c                PROVIDE (edata, .)
+                0x00008e7c                __bss_start = .
+                0x00008e7c                __bss_start__ = .
+
+.bss            0x00008e7c     0x3024
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ .bss           0x00008e7c     0x3000 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/cccPBW5f.o
+                0x00008e7c                _stack_base
+                0x0000be7c                _start_bss_clear
+                0x00009e7c                _workarea
+                0x00009e7c                _stack_start
+ .bss.flash_info
+                0x0000be7c       0x20 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+                0x0000be7c                flash_info
+ .bss.flash_dev_info
+                0x0000be9c        0x4 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+ *(COMMON)
+                0x0000bea0                . = ALIGN (0x4)
+                0x0000bea0                . = ALIGN (0x4)
+                0x0000bea0                _end = .
+                0x0000bea0                _bss_end__ = .
+                0x0000bea0                __bss_end__ = .
+                0x0000bea0                __end__ = .
+                0x0000bea0                PROVIDE (end, .)
+
+.stab
+ *(.stab)
+
+.stabstr
+ *(.stabstr)
+
+.stab.excl
+ *(.stab.excl)
+
+.stab.exclstr
+ *(.stab.exclstr)
+
+.stab.index
+ *(.stab.index)
+
+.stab.indexstr
+ *(.stab.indexstr)
+
+.comment
+ *(.comment)
+
+.debug
+ *(.debug)
+
+.line
+ *(.line)
+
+.debug_srcinfo
+ *(.debug_srcinfo)
+
+.debug_sfnames
+ *(.debug_sfnames)
+
+.debug_aranges  0x00000000      0x170
+ *(.debug_aranges)
+ .debug_aranges
+                0x00000000       0x20 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/cccPBW5f.o
+ .debug_aranges
+                0x00000020       0x48 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+ .debug_aranges
+                0x00000068       0x68 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+ .debug_aranges
+                0x000000d0       0x50 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+ .debug_aranges
+                0x00000120       0x28 /tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+ .debug_aranges
+                0x00000148       0x28 /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+
+.debug_pubnames
+                0x00000000      0x1e5
+ *(.debug_pubnames)
+ .debug_pubnames
+                0x00000000       0x4d /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+ .debug_pubnames
+                0x0000004d       0xca /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+ .debug_pubnames
+                0x00000117       0x91 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+ .debug_pubnames
+                0x000001a8       0x1e /tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+ .debug_pubnames
+                0x000001c6       0x1f /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+
+.debug_info     0x00000000     0x1122
+ *(.debug_info .gnu.linkonce.wi.*)
+ .debug_info    0x00000000       0x6e /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/cccPBW5f.o
+ .debug_info    0x0000006e      0x322 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+ .debug_info    0x00000390      0x4f6 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+ .debug_info    0x00000886      0x5b2 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+ .debug_info    0x00000e38      0x1c7 /tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+ .debug_info    0x00000fff      0x123 /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+
+.debug_abbrev   0x00000000      0x67c
+ *(.debug_abbrev)
+ .debug_abbrev  0x00000000       0x14 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/cccPBW5f.o
+ .debug_abbrev  0x00000014      0x17d /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+ .debug_abbrev  0x00000191      0x15f /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+ .debug_abbrev  0x000002f0      0x238 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+ .debug_abbrev  0x00000528       0xb4 /tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+ .debug_abbrev  0x000005dc       0xa0 /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+
+.debug_line     0x00000000      0x8de
+ *(.debug_line)
+ .debug_line    0x00000000       0x3e /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/cccPBW5f.o
+ .debug_line    0x0000003e       0xf6 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+ .debug_line    0x00000134      0x255 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+ .debug_line    0x00000389      0x287 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+ .debug_line    0x00000610      0x16c /tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+ .debug_line    0x0000077c      0x162 /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+
+.debug_frame    0x00000000      0x2c0
+ *(.debug_frame)
+ .debug_frame   0x00000000       0xa4 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+ .debug_frame   0x000000a4      0x110 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+ .debug_frame   0x000001b4       0xac /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+ .debug_frame   0x00000260       0x38 /tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+ .debug_frame   0x00000298       0x28 /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+
+.debug_str      0x00000000      0x508
+ *(.debug_str)
+ .debug_str     0x00000000      0x131 /ecos-c/DOCUME~1/oyvind/LOCALS~1/Temp/ccM8Ftqt.o
+                                0x191 (size before relaxing)
+ .debug_str     0x00000131      0x152 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+                                0x24e (size before relaxing)
+ .debug_str     0x00000283      0x194 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+                                0x2c5 (size before relaxing)
+ .debug_str     0x00000417       0x7e /tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+                                0x11e (size before relaxing)
+ .debug_str     0x00000495       0x73 /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
+                                0x119 (size before relaxing)
+
+.debug_loc
+ *(.debug_loc)
+
+.debug_macinfo
+ *(.debug_macinfo)
+
+.debug_weaknames
+ *(.debug_weaknames)
+
+.debug_funcnames
+ *(.debug_funcnames)
+
+.debug_typenames
+ *(.debug_typenames)
+
+.debug_varnames
+ *(.debug_varnames)
+
+.stack          0x00080000        0x0
+                0x00080000                _stack = .
+ *(.stack)
+
+.note.gnu.arm.ident
+ *(.note.gnu.arm.ident)
+
+/DISCARD/
+ *(.note.GNU-stack)
+OUTPUT(debug_eb40a.elf elf32-littlearm)
+
+.debug_ranges   0x00000000       0xb8
+ .debug_ranges  0x00000000       0x18 /tmp/ecosboard/ecos/install/lib/libtarget.a(io_flash_flash.o)
+ .debug_ranges  0x00000018       0x48 /tmp/ecosboard/ecos/install/lib/libtarget.a(devs_flash_arm_eb40a_eb40a_flash.o)
+ .debug_ranges  0x00000060       0x30 /tmp/ecosboard/ecos/install/lib/libtarget.a(infra_memcpy.o)
+ .debug_ranges  0x00000090       0x28 /tmp/ecosboard/ecos/install/lib/libtarget.a(language_c_libc_string_memcmp.o)
diff --git a/ecosflash/notes.txt b/ecosflash/notes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..218391273f57d0891e5ecbcc412163c9b4f5901a
--- /dev/null
+++ b/ecosflash/notes.txt
@@ -0,0 +1,111 @@
+1. GDB startup script for debugging purposes.
+
+# startup script for debugging flash erase
+target remote 10.0.0.56:2001
+monitor halt
+monitor reset
+load
+# stack
+monitor rm 13 0x7000
+# pc 
+monitor rm 15 0x8000
+# arg1 to erase()
+monitor rm 0 0x1030000
+# arg2 to erase()
+monitor rm 1 0x10000
+stepi
+
+
+
+2. Uploading flash driver via tftp
+
+
+$ tftp 10.0.0.108
+tftp> binary
+tftp> put at91fr40162.bin 10.0.0.108:/config/flashdriver.bin
+Sent 4048 bytes in 0.1 seconds
+tftp>
+
+
+4. Programming flash
+
+eCosBoard_prog 0x1000000 /config/testdata.bin
+ 
+ 
+tftp> put /cygdrive/c/workspace/ecosboard/ecosboard/phi/bootloader/images/bootloader.bin 10.0.0.108:/config/test.bin
+Sent 165724 bytes in 3.9 seconds
+
+
+halt
+reg cpsr 0x000000D3
+mww 0xFFE00020 0x1
+mww 0xFFE00024 0x00000000
+mww 0xFFE00000 0x01002539
+eCosBoard_profile
+eCosBoard_prog /config/test.bin 0x1000000
+eCosBoard_profile_done
+
+
+
+
+set remote memory-write-packet-size fixed
+
+
+set remote memory-write-packet-size 8192
+set remote memory-map-packet on
+target remote 10.0.0.108:3333
+monitor halt
+monitor reg cpsr 0x000000D3
+monitor mww 0xFFE00020 0x1
+monitor mww 0xFFE00024 0x00000000
+monitor mww 0xFFE00000 0x01002539
+
+
+monitor eCosBoard_profile
+load
+monitor eCosBoard_profile_done
+
+
+source /tmp/ecosboard/packages/services/profile/gprof/current/host/gprof.gdb
+gprof_dump
+shell cp gmon.out /tmp/ecosboard/build/src
+echo To view: cd /tmp/ecosboard/build/src && gprof openocd
+
+
+Performance problems:
+
+It seems the problem is that the actual flash programming takes time. 
+hal_delay_us() is invoked between each time the 
+CPU is polled for whether flash programming has completed.
+
+
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+  %   cumulative   self              self     total
+ time   seconds   seconds    calls  Ts/call  Ts/call  name
+ 35.82     37.66    37.66                             hal_delay_us
+ 11.90     50.17    12.51                             arm7tdmi_clock_out
+  9.86     60.54    10.37                             gdb_get_packet
+  5.36     66.17     5.63                             memcpy
+  4.34     70.73     4.56                             target_buffer_get_u32
+  3.34     74.25     3.51                             embeddedice_read_reg_w_che
+ck
+  1.39     75.71     1.46                             arm7_9_write_memory
+  1.34     77.11     1.40                             cyg_tcp_output
+  1.33     78.51     1.40                             __udivsi3
+  1.11     79.68     1.17                             cyg_tcp_input
+  1.07     80.80     1.13                             arm7tdmi_store_word_regs
+  0.95     81.81     1.00                             __udivdi3
+  0.95     82.80     1.00                             __umodsi3
+  0.93     83.78     0.98                             arm7tdmi_write_core_regs
+  0.86     84.68     0.91                             arm7_9_poll
+  0.85     85.57     0.89                             memset
+  0.77     86.38     0.81                             cyg_splx
+  0.64     87.05     0.67                             cyg_in_cksumdata
+  0.63     87.71     0.66                             openeth_deliver
+  0.57     88.31     0.60                             strstr
+  0.51     88.85     0.53                             eth_drv_recv
+  0.49     89.36     0.52                             cyg_splinternal
+  0.49     89.88     0.52                             cyg_splimp
+  0.46     90.36     0.48                             cyg_ip_input
\ No newline at end of file
diff --git a/src/flash/Makefile.am b/src/flash/Makefile.am
index 90f009e9161f7eb25104b8a30f422965ad5eae05..4d0280f610b96858e605ec118ee6b36012a986db 100644
--- a/src/flash/Makefile.am
+++ b/src/flash/Makefile.am
@@ -3,7 +3,7 @@ AM_CPPFLAGS = -DPKGLIBDIR=\"$(pkglibdir)\" @CPPFLAGS@
 METASOURCES = AUTO
 noinst_LIBRARIES = libflash.a
 libflash_a_SOURCES = flash.c lpc2000.c cfi.c non_cfi.c at91sam7.c str7x.c str9x.c nand.c lpc3180_nand_controller.c \
-					 stellaris.c str9xpec.c stm32x.c tms470.c \
+					 stellaris.c str9xpec.c stm32x.c tms470.c ecos.c  \
 		     s3c24xx_nand.c s3c2410_nand.c s3c2412_nand.c s3c2440_nand.c s3c2443_nand.c
 noinst_HEADERS = flash.h lpc2000.h cfi.h non_cfi.h at91sam7.h str7x.h str9x.h nand.h lpc3180_nand_controller.h \
 				 stellaris.h str9xpec.h stm32x.h tms470.h s3c24xx_nand.h s3c24xx_regs_nand.h
diff --git a/src/flash/ecos.c b/src/flash/ecos.c
new file mode 100644
index 0000000000000000000000000000000000000000..6aec41d6a370b83a0553e404b3ee9c5a38e884a0
--- /dev/null
+++ b/src/flash/ecos.c
@@ -0,0 +1,481 @@
+/***************************************************************************
+ *   Copyright (C) 2008 �yvind Harboe                                      *
+ *   oyvind.harboe@zylin.com                                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 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 General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "replacements.h"
+
+
+#include "flash.h"
+
+#include "target.h"
+
+#include "flash.h"
+#include "target.h"
+#include "log.h"
+#include "binarybuffer.h"
+#include "../target/embeddedice.h"
+#include "types.h"
+
+
+
+int ecosflash_register_commands(struct command_context_s *cmd_ctx);
+int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
+int ecosflash_erase(struct flash_bank_s *bank, int first, int last);
+int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last);
+int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
+int ecosflash_probe(struct flash_bank_s *bank);
+int ecosflash_erase_check(struct flash_bank_s *bank);
+int ecosflash_protect_check(struct flash_bank_s *bank);
+int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size);
+
+u32 ecosflash_get_flash_status(flash_bank_t *bank);
+void ecosflash_set_flash_mode(flash_bank_t *bank,int mode);
+u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout);
+int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+
+flash_driver_t ecosflash_flash =
+{
+	.name = "ecosflash",
+	.register_commands = ecosflash_register_commands,
+	.flash_bank_command = ecosflash_flash_bank_command,
+	.erase = ecosflash_erase,
+	.protect = ecosflash_protect,
+	.write = ecosflash_write,
+	.probe = ecosflash_probe,
+	.auto_probe = ecosflash_probe,
+	.erase_check = ecosflash_erase_check,
+	.protect_check = ecosflash_protect_check,
+	.info = ecosflash_info
+};
+
+typedef struct ecosflash_flash_bank_s
+{
+	struct target_s *target;
+	working_area_t *write_algorithm;
+	working_area_t *erase_check_algorithm;
+	char *driverPath;
+	u32 start_address;
+} ecosflash_flash_bank_t;
+
+static const int sectorSize=0x10000;
+
+#define FLASH_ERR_OK              0x00  // No error - operation complete
+#define FLASH_ERR_INVALID         0x01  // Invalid FLASH address
+#define FLASH_ERR_ERASE           0x02  // Error trying to erase
+#define FLASH_ERR_LOCK            0x03  // Error trying to lock/unlock
+#define FLASH_ERR_PROGRAM         0x04  // Error trying to program
+#define FLASH_ERR_PROTOCOL        0x05  // Generic error
+#define FLASH_ERR_PROTECT         0x06  // Device/region is write-protected
+#define FLASH_ERR_NOT_INIT        0x07  // FLASH info not yet initialized
+#define FLASH_ERR_HWR             0x08  // Hardware (configuration?) problem
+#define FLASH_ERR_ERASE_SUSPEND   0x09  // Device is in erase suspend mode
+#define FLASH_ERR_PROGRAM_SUSPEND 0x0a  // Device is in in program suspend mode
+#define FLASH_ERR_DRV_VERIFY      0x0b  // Driver failed to verify data
+#define FLASH_ERR_DRV_TIMEOUT     0x0c  // Driver timed out waiting for device
+#define FLASH_ERR_DRV_WRONG_PART  0x0d  // Driver does not support device
+#define FLASH_ERR_LOW_VOLTAGE     0x0e  // Not enough juice to complete job
+
+
+char *
+flash_errmsg(int err)
+{
+    switch (err) {
+    case FLASH_ERR_OK:
+        return "No error - operation complete";
+    case FLASH_ERR_ERASE_SUSPEND:
+        return "Device is in erase suspend state";
+    case FLASH_ERR_PROGRAM_SUSPEND:
+        return "Device is in program suspend state";
+    case FLASH_ERR_INVALID:
+        return "Invalid FLASH address";
+    case FLASH_ERR_ERASE:
+        return "Error trying to erase";
+    case FLASH_ERR_LOCK:
+        return "Error trying to lock/unlock";
+    case FLASH_ERR_PROGRAM:
+        return "Error trying to program";
+    case FLASH_ERR_PROTOCOL:
+        return "Generic error";
+    case FLASH_ERR_PROTECT:
+        return "Device/region is write-protected";
+    case FLASH_ERR_NOT_INIT:
+        return "FLASH sub-system not initialized";
+    case FLASH_ERR_DRV_VERIFY:
+        return "Data verify failed after operation";
+    case FLASH_ERR_DRV_TIMEOUT:
+        return "Driver timed out waiting for device";
+    case FLASH_ERR_DRV_WRONG_PART:
+        return "Driver does not support device";
+    case FLASH_ERR_LOW_VOLTAGE:
+        return "Device reports low voltage";
+    default:
+        return "Unknown error";
+    }
+}
+
+
+/* flash bank ecosflash <base> <size> <chip_width> <bus_width> <target#> <driverPath>
+ */
+int ecosflash_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
+{
+	ecosflash_flash_bank_t *info;
+	
+	if (argc < 7)
+	{
+		WARNING("incomplete flash_bank ecosflash configuration");
+		return ERROR_FLASH_BANK_INVALID;
+	}
+	
+	info = malloc(sizeof(ecosflash_flash_bank_t));
+	if(info == NULL)
+	{
+		ERROR("no memory for flash bank info");
+		exit(-1);
+	}
+	bank->driver_priv = info;
+	info->driverPath=strdup(args[6]);
+
+	// eCos flash sector sizes are not exposed to OpenOCD, use 0x10000 as 
+	// a way to improve impeadance matach between OpenOCD and eCos flash
+	// driver
+	int i = 0;
+	u32 offset = 0;
+	bank->num_sectors=bank->size/sectorSize;
+	bank->sectors = malloc(sizeof(flash_sector_t) * bank->num_sectors);
+	for (i = 0; i < bank->num_sectors; i++)
+	{
+		bank->sectors[i].offset = offset;
+		bank->sectors[i].size = sectorSize;
+		offset += bank->sectors[i].size;
+		bank->sectors[i].is_erased = -1;
+		bank->sectors[i].is_protected = 0;
+	}
+	
+	info->target = get_target_by_num(strtoul(args[5], NULL, 0));
+	if (info->target == NULL)
+	{
+		ERROR("no target '%i' configured", (int)strtoul(args[5], NULL, 0));
+		exit(-1);
+	}
+	return ERROR_OK;
+}
+
+
+int loadDriver(ecosflash_flash_bank_t *info)
+{
+	u32 buf_cnt;
+	u32 image_size;
+	image_t image;	
+	
+	image.base_address_set = 0;
+	image.start_address_set = 0;
+	target_t *target=info->target;
+	
+	if (image_open(&image, info->driverPath, NULL) != ERROR_OK)
+	{
+		ERROR("load_image error: %s", image.error_str);
+		return ERROR_FLASH_BANK_INVALID;
+	}
+	
+	info->start_address=image.start_address;
+	
+	image_size = 0x0;
+	int i;
+	for (i = 0; i < image.num_sections; i++)
+	{
+		void *buffer = malloc(image.sections[i].size);
+		int retval;
+		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
+		{
+			ERROR("image_read_section failed with error code: %i", retval);
+			free(buffer);
+			image_close(&image);
+			return ERROR_FLASH_BANK_INVALID;
+		}
+		target_write_buffer(target, image.sections[i].base_address, buf_cnt, buffer);
+		image_size += buf_cnt;
+		DEBUG("%u byte written at address 0x%8.8x", buf_cnt, image.sections[i].base_address);
+		
+		free(buffer);
+	}
+
+	image_close(&image);
+
+	return ERROR_OK;
+}
+
+
+static int const OFFSET_ERASE=0x0;
+static int const OFFSET_ERASE_SIZE=0x8;
+static int const OFFSET_FLASH=0xc;
+static int const OFFSET_FLASH_SIZE=0x8;
+static int const OFFSET_GET_WORKAREA=0x18;
+static int const OFFSET_GET_WORKAREA_SIZE=0x4;
+
+
+int runCode(ecosflash_flash_bank_t *info, 
+		u32 codeStart, u32 codeStop, u32 r0, u32 r1, u32 r2, 
+		u32 *result,
+		// timeout in ms
+		int timeout)
+{
+	target_t *target=info->target;
+
+	reg_param_t reg_params[3];
+	armv4_5_algorithm_t armv4_5_info;
+	armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
+	armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
+	armv4_5_info.core_state = ARMV4_5_STATE_ARM;
+	
+	init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
+	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+	init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
+	
+	buf_set_u32(reg_params[0].value, 0, 32, r0);
+	buf_set_u32(reg_params[1].value, 0, 32, r1);
+	buf_set_u32(reg_params[2].value, 0, 32, r2);
+	
+	int retval;
+	if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params,
+			codeStart,
+			codeStop, timeout, 
+			&armv4_5_info)) != ERROR_OK)
+	{
+		ERROR("error executing eCos flash algorithm");
+		return retval;
+	}
+	
+	*result=buf_get_u32(reg_params[0].value, 0, 32);
+	
+	destroy_reg_param(&reg_params[0]);
+	destroy_reg_param(&reg_params[1]);
+	destroy_reg_param(&reg_params[2]);
+	
+	return ERROR_OK;
+}
+
+int eCosBoard_erase(ecosflash_flash_bank_t *info, u32 address, u32 len)
+{
+	int retval;
+	int timeout = (len / 20480 + 1) * 1000; /*asume 20 KB/s*/ 
+
+	retval=loadDriver(info);
+	if (retval!=ERROR_OK)
+		return retval;
+	
+	u32 flashErr;
+	retval=runCode(info, 
+			info->start_address+OFFSET_ERASE,
+			info->start_address+OFFSET_ERASE+OFFSET_ERASE_SIZE,
+			address,
+			len,
+			0,
+			&flashErr,
+			timeout
+			);
+	if (retval!=ERROR_OK)
+		return retval;
+	
+	if (flashErr != 0x0)
+	{
+		ERROR("Flash erase failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
+		return ERROR_JTAG_DEVICE_ERROR;
+	}
+
+	return ERROR_OK;
+}
+
+int eCosBoard_flash(ecosflash_flash_bank_t *info, void *data, u32 address, u32 len)
+{
+	target_t *target=info->target;
+	const int chunk=8192;
+	int retval=ERROR_OK;
+	int timeout = (chunk / 20480 + 1) * 1000; /*asume 20 KB/s + 1 second*/
+	
+	retval=loadDriver(info);
+	if (retval!=ERROR_OK)
+		return retval;
+	
+	u32 buffer;
+	retval=runCode(info, 
+			info->start_address+OFFSET_GET_WORKAREA,
+			info->start_address+OFFSET_GET_WORKAREA+OFFSET_GET_WORKAREA_SIZE,
+			0,
+			0,
+			0,
+			&buffer,
+			1000);
+	if (retval!=ERROR_OK)
+		return retval;
+	
+	
+	int i;
+    for (i=0; i<len; i+=chunk)
+    {
+		int t=len-i;
+		if (t>chunk)
+		{
+			t=chunk;
+		}
+		
+		int retval;
+    	retval=target_write_buffer(target, buffer, t, ((char *)data)+i);
+    	if (retval != ERROR_OK)
+    		return retval;
+    	
+    	u32 flashErr;
+    	retval=runCode(info, 
+    			info->start_address+OFFSET_FLASH,
+    			info->start_address+OFFSET_FLASH+OFFSET_FLASH_SIZE,
+    			buffer,
+    			address+i,
+    			t,
+    			&flashErr,
+    			timeout);
+    	if (retval != ERROR_OK)
+    		return retval;
+
+		if (flashErr != 0x0)
+		{
+			ERROR("Flash prog failed with %d (%s)\n", flashErr, flash_errmsg(flashErr));
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
+    }
+	return ERROR_OK;
+}
+
+
+int ecosflash_probe(struct flash_bank_s *bank)
+{
+	return ERROR_OK;
+}
+
+
+int ecosflash_register_commands(struct command_context_s *cmd_ctx)
+{
+	register_command(cmd_ctx, NULL, "ecosflash", NULL, COMMAND_ANY, NULL);
+	
+	return ERROR_OK;
+}
+
+/*
+static void command(flash_bank_t *bank, u8 cmd, u8 *cmd_buf)
+{
+	ecosflash_flash_bank_t *info = bank->driver_priv;
+	int i;
+	
+	if (info->target->endianness == TARGET_LITTLE_ENDIAN)
+	{
+		for (i = bank->bus_width; i > 0; i--)
+		{
+			*cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
+		}
+	}
+	else
+	{
+		for (i = 1; i <= bank->bus_width; i++)
+		{
+			*cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;
+		}
+	}
+}
+*/
+
+u32 ecosflash_address(struct flash_bank_s *bank, u32 address)
+{
+	u32 retval = 0;
+	switch(bank->bus_width)
+	{
+		case 4:
+			retval = address & 0xfffffffc;
+		case 2:
+			retval = address & 0xfffffffe;
+		case 1:
+			retval = address;
+	}
+	
+	return retval + bank->base;
+} 
+
+
+int ecosflash_erase(struct flash_bank_s *bank, int first, int last)
+{
+	struct flash_bank_s *c=bank;
+	ecosflash_flash_bank_t *info = bank->driver_priv;
+	return eCosBoard_erase(info, c->base+first*sectorSize, sectorSize*(last-first+1)); 
+}
+
+int ecosflash_protect(struct flash_bank_s *bank, int set, int first, int last)
+{
+	return ERROR_OK;
+}
+
+
+int ecosflash_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
+{
+	ecosflash_flash_bank_t *info = bank->driver_priv;
+	struct flash_bank_s *c=bank;
+	return eCosBoard_flash(info, buffer, c->base+offset, count);
+}
+
+
+int ecosflash_erase_check(struct flash_bank_s *bank)
+{
+	return ERROR_OK;
+}
+
+int ecosflash_protect_check(struct flash_bank_s *bank)
+{
+	return ERROR_OK;
+}
+
+int ecosflash_info(struct flash_bank_s *bank, char *buf, int buf_size)
+{
+	ecosflash_flash_bank_t *info = bank->driver_priv;
+	snprintf(buf, buf_size, "eCos flash driver: %s", info->driverPath);
+	return ERROR_OK;
+}
+
+
+u32 ecosflash_get_flash_status(flash_bank_t *bank)
+{
+	return ERROR_OK;
+}
+
+void ecosflash_set_flash_mode(flash_bank_t *bank,int mode)
+{
+	
+}
+
+u32 ecosflash_wait_status_busy(flash_bank_t *bank, u32 waitbits, int timeout)
+{
+	return ERROR_OK;
+}
+
+int ecosflash_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+	return ERROR_OK;
+}
+
+
+
+
diff --git a/src/flash/flash.c b/src/flash/flash.c
index 2fefb4cd7668586f403ea20b218554fb821961f7..f1710851cfd642f7493f8d234fb8ef72f4c813ca 100644
--- a/src/flash/flash.c
+++ b/src/flash/flash.c
@@ -64,6 +64,7 @@ extern flash_driver_t stellaris_flash;
 extern flash_driver_t str9xpec_flash;
 extern flash_driver_t stm32x_flash;
 extern flash_driver_t tms470_flash;
+extern flash_driver_t ecosflash_flash;
 
 flash_driver_t *flash_drivers[] =
 {
@@ -76,6 +77,7 @@ flash_driver_t *flash_drivers[] =
 	&str9xpec_flash,
 	&stm32x_flash,
 	&tms470_flash,
+	&ecosflash_flash,
 	NULL,
 };