Browse Source

eCos flash driver.

git-svn-id: svn://svn.berlios.de/openocd/trunk@365 b42882b7-edfa-0310-969c-e2dbd0fdcd60
tags/v0.1.0
oharboe 14 years ago
parent
commit
d17e1cd933
10 changed files with 1126 additions and 1 deletions
  1. +11
    -0
      ecosflash/Makefile
  2. BIN
      ecosflash/at91eb40a.elf
  3. BIN
      ecosflash/debug_at91eb40a.elf
  4. +58
    -0
      ecosflash/flash.S
  5. +72
    -0
      ecosflash/flash.c
  6. +390
    -0
      ecosflash/flash.map
  7. +111
    -0
      ecosflash/notes.txt
  8. +1
    -1
      src/flash/Makefile.am
  9. +481
    -0
      src/flash/ecos.c
  10. +2
    -0
      src/flash/flash.c

+ 11
- 0
ecosflash/Makefile View File

@@ -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


BIN
ecosflash/at91eb40a.elf View File


BIN
ecosflash/debug_at91eb40a.elf View File


+ 58
- 0
ecosflash/flash.S View File

@@ -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:

+ 72
- 0
ecosflash/flash.c View File

@@ -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);
}

+ 390
- 0
ecosflash/flash.map View File

@@ -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)

+ 111
- 0
ecosflash/notes.txt View File

@@ -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

+ 1
- 1
src/flash/Makefile.am View File

@@ -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

+ 481
- 0
src/flash/ecos.c View File

@@ -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;
}

+ 2
- 0
src/flash/flash.c View File

@@ -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,
};



Loading…
Cancel
Save