diff options
-rw-r--r-- | ecosflash/Makefile | 11 | ||||
-rw-r--r-- | ecosflash/at91eb40a.elf | bin | 0 -> 36832 bytes | |||
-rw-r--r-- | ecosflash/debug_at91eb40a.elf | bin | 0 -> 49447 bytes | |||
-rw-r--r-- | ecosflash/flash.S | 58 | ||||
-rw-r--r-- | ecosflash/flash.c | 72 | ||||
-rw-r--r-- | ecosflash/flash.map | 390 | ||||
-rw-r--r-- | ecosflash/notes.txt | 111 | ||||
-rw-r--r-- | src/flash/Makefile.am | 2 | ||||
-rw-r--r-- | src/flash/ecos.c | 481 | ||||
-rw-r--r-- | src/flash/flash.c | 2 |
10 files changed, 1126 insertions, 1 deletions
diff --git a/ecosflash/Makefile b/ecosflash/Makefile new file mode 100644 index 00000000..dfff37c2 --- /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 Binary files differnew file mode 100644 index 00000000..451657a5 --- /dev/null +++ b/ecosflash/at91eb40a.elf diff --git a/ecosflash/debug_at91eb40a.elf b/ecosflash/debug_at91eb40a.elf Binary files differnew file mode 100644 index 00000000..0bada05a --- /dev/null +++ b/ecosflash/debug_at91eb40a.elf diff --git a/ecosflash/flash.S b/ecosflash/flash.S new file mode 100644 index 00000000..dc30d163 --- /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 00000000..654273d3 --- /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 00000000..d47258b7 --- /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 00000000..21839127 --- /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 90f009e9..4d0280f6 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 00000000..6aec41d6 --- /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(®_params[0], "r0", 32, PARAM_IN_OUT);
+ init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
+ init_reg_param(®_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(®_params[0]);
+ destroy_reg_param(®_params[1]);
+ destroy_reg_param(®_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 2fefb4cd..f1710851 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, }; |