git-svn-id: svn://svn.berlios.de/openocd/trunk@365 b42882b7-edfa-0310-969c-e2dbd0fdcd60tags/v0.1.0
@@ -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 | |||
@@ -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: |
@@ -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); | |||
} |
@@ -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) |
@@ -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 |
@@ -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 |
@@ -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; | |||
} | |||
@@ -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, | |||
}; | |||