From 0fc635b3f8a961d09a7ac784d7846c785a3345dc Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 22 Mar 2015 22:59:04 -0700 Subject: Add functions for dynamically generating the XML memory map. --- src/include/target.h | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src/include/target.h') diff --git a/src/include/target.h b/src/include/target.h index 940a360..5a9a94a 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -112,12 +112,27 @@ target *target_attach(target *t, target_destroy_callback destroy_cb); #define target_regs_size(target) \ ((target)->regs_size) -#define target_mem_map(target) \ - ((target)->xml_mem_map ? (target)->xml_mem_map : "") - #define target_tdesc(target) \ ((target)->tdesc ? (target)->tdesc : "") +struct target_ram { + uint32_t start; + uint32_t length; + struct target_ram *next; +}; + +struct target_flash { + uint32_t start; + uint32_t length; + uint32_t blocksize; + int (*erase)(struct target_flash *f, uint32_t addr, size_t len); + int (*write)(struct target_flash *f, uint32_t dest, + const uint8_t *src, size_t len); + int (*done)(struct target_flash *t); + target *t; + struct target_flash *next; +}; + struct target_s { /* Notify controlling debugger if target is lost */ target_destroy_callback destroy_callback; @@ -158,8 +173,12 @@ struct target_s { unsigned target_options; uint32_t idcode; - /* Flash memory access functions */ + /* Target memory map */ const char *xml_mem_map; + struct target_ram *ram; + struct target_flash *flash; + + /* DEPRECATED: Flash memory access functions */ int (*flash_erase)(target *t, uint32_t addr, size_t len); int (*flash_write)(target *t, uint32_t dest, const uint8_t *src, size_t len); @@ -190,6 +209,9 @@ extern bool connect_assert_srst; target *target_new(unsigned size); void target_list_free(void); void target_add_commands(target *t, const struct command_s *cmds, const char *name); +void target_add_ram(target *t, uint32_t start, uint32_t len); +void target_add_flash(target *t, struct target_flash *f); +const char *target_mem_map(target *t); static inline uint32_t target_mem_read32(target *t, uint32_t addr) { -- cgit v1.2.3 From 691d21989a6957be728635fe8b56720c21758a3f Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 24 Mar 2015 20:45:05 -0700 Subject: Add function to add simple flash driver to target. Clean up ram/flash/memory map on target destruction. --- src/include/target.h | 13 +++++++++---- src/target.c | 20 ++++++++++++++++++-- 2 files changed, 27 insertions(+), 6 deletions(-) (limited to 'src/include/target.h') diff --git a/src/include/target.h b/src/include/target.h index 5a9a94a..7085ff2 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -121,14 +121,18 @@ struct target_ram { struct target_ram *next; }; +struct target_flash; +typedef int (*flash_erase_func)(struct target_flash *f, uint32_t addr, size_t len); +typedef int (*flash_write_func)(struct target_flash *f, uint32_t dest, + const void *src, size_t len); +typedef int (*flash_done_func)(struct target_flash *f); struct target_flash { uint32_t start; uint32_t length; uint32_t blocksize; - int (*erase)(struct target_flash *f, uint32_t addr, size_t len); - int (*write)(struct target_flash *f, uint32_t dest, - const uint8_t *src, size_t len); - int (*done)(struct target_flash *t); + flash_erase_func erase; + flash_write_func write; + flash_done_func done; target *t; struct target_flash *next; }; @@ -175,6 +179,7 @@ struct target_s { /* Target memory map */ const char *xml_mem_map; + char *dyn_mem_map; struct target_ram *ram; struct target_flash *flash; diff --git a/src/target.c b/src/target.c index 4e10e72..86d88ed 100644 --- a/src/target.c +++ b/src/target.c @@ -48,6 +48,18 @@ void target_list_free(void) free(target_list->commands); target_list->commands = tc; } + if (target_list->dyn_mem_map) + free(target_list->dyn_mem_map); + while (target_list->ram) { + void * next = target_list->ram->next; + free(target_list->ram); + target_list->ram = next; + } + while (target_list->flash) { + void * next = target_list->flash->next; + free(target_list->flash); + target_list->flash = next; + } free(target_list); target_list = t; } @@ -117,9 +129,13 @@ static ssize_t map_flash(char *buf, size_t len, struct target_flash *f) const char *target_mem_map(target *t) { + /* Deprecated static const memory map */ if (t->xml_mem_map) return t->xml_mem_map; + if (t->dyn_mem_map) + return t->dyn_mem_map; + /* FIXME size buffer */ size_t len = 1024; char *tmp = malloc(len); @@ -133,8 +149,8 @@ const char *target_mem_map(target *t) i += map_flash(&tmp[i], len - i, f); i += snprintf(&tmp[i], len - i, ""); - t->xml_mem_map = tmp; + t->dyn_mem_map = tmp; - return t->xml_mem_map; + return t->dyn_mem_map; } -- cgit v1.2.3 From 7202db586038843d1d4f01403ce6e1285ac3520c Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 24 Mar 2015 20:45:59 -0700 Subject: Add new functions to wrap flash driver erase/write/done operations. --- src/include/target.h | 12 ++++-------- src/target.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 8 deletions(-) (limited to 'src/include/target.h') diff --git a/src/include/target.h b/src/include/target.h index 7085ff2..bcabc23 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -95,14 +95,10 @@ target *target_attach(target *t, target_destroy_callback destroy_cb); /* Flash memory access functions */ -#define target_flash_erase(target, addr, len) \ - (target)->flash_erase((target), (addr), (len)) - -#define target_flash_write(target, dest, src, len) \ - (target)->flash_write((target), (dest), (src), (len)) - -#define target_flash_done(target) \ - ((target)->flash_done ? (target)->flash_done(target) : 0) +int target_flash_erase(target *t, uint32_t addr, size_t len); +int target_flash_write(target *t, + uint32_t dest, const void *src, size_t len); +int target_flash_done(target *t); /* Host I/O */ #define target_hostio_reply(target, recode, errcode) \ diff --git a/src/target.c b/src/target.c index 86d88ed..6b05deb 100644 --- a/src/target.c +++ b/src/target.c @@ -154,3 +154,57 @@ const char *target_mem_map(target *t) return t->dyn_mem_map; } +static struct target_flash *flash_for_addr(target *t, uint32_t addr) +{ + for (struct target_flash *f = t->flash; f; f = f->next) + if ((f->start <= addr) && + (addr < (f->start + f->length))) + return f; + return NULL; +} + +int target_flash_erase(target *t, uint32_t addr, size_t len) +{ + if (t->flash_write) + return t->flash_erase(t, addr, len); + + int ret = 0; + while (len) { + struct target_flash *f = flash_for_addr(t, addr); + size_t tmplen = MIN(len, f->length - (addr % f->length)); + ret |= f->erase(f, addr, tmplen); + addr += tmplen; + len -= tmplen; + } + return ret; +} + +int target_flash_write(target *t, + uint32_t dest, const void *src, size_t len) +{ + if (t->flash_write) + return t->flash_write(t, dest, src, len); + + int ret = 0; + while (len) { + struct target_flash *f = flash_for_addr(t, dest); + size_t tmplen = MIN(len, f->length - (dest % f->length)); + ret |= f->write(f, dest, src, tmplen); + src += tmplen; + len -= tmplen; + } + return ret; +} + +int target_flash_done(target *t) +{ + for (struct target_flash *f = t->flash; f; f = f->next) { + if (f->done) { + int tmp = f->done(f); + if (tmp) + return tmp; + } + } + return 0; +} + -- cgit v1.2.3 From 36f749fed92597e0469909e5399146359e5fdfdf Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Thu, 26 Mar 2015 22:18:18 -0700 Subject: Fix flash buffer alignment in target layer. --- src/include/target.h | 2 ++ src/target.c | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/include/target.h') diff --git a/src/include/target.h b/src/include/target.h index bcabc23..f49bc58 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -131,6 +131,8 @@ struct target_flash { flash_done_func done; target *t; struct target_flash *next; + int align; + uint8_t erased; }; struct target_s { diff --git a/src/target.c b/src/target.c index 6b05deb..3ab59bc 100644 --- a/src/target.c +++ b/src/target.c @@ -189,7 +189,15 @@ int target_flash_write(target *t, while (len) { struct target_flash *f = flash_for_addr(t, dest); size_t tmplen = MIN(len, f->length - (dest % f->length)); - ret |= f->write(f, dest, src, tmplen); + if (f->align > 1) { + uint32_t offset = dest % f->align; + uint8_t data[ALIGN(offset + len, f->align)]; + memset(data, f->erased, sizeof(data)); + memcpy((uint8_t *)data + offset, src, len); + ret |= f->write(f, dest - offset, data, sizeof(data)); + } else { + ret |= f->write(f, dest, src, tmplen); + } src += tmplen; len -= tmplen; } -- cgit v1.2.3 From 45328ea12498e857262ae571710d01cb38302a9f Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Thu, 26 Mar 2015 22:20:47 -0700 Subject: Add buffering support for flash drivers. Some devices can get a significant boost in performance by writing to flash memories one page at a time. Generic function to do this are provided at the target layer and may be used by flash drivers. --- src/include/target.h | 9 +++++++++ src/target.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) (limited to 'src/include/target.h') diff --git a/src/include/target.h b/src/include/target.h index f49bc58..96b5506 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -133,6 +133,12 @@ struct target_flash { struct target_flash *next; int align; uint8_t erased; + + /* For buffered flash */ + size_t buf_size; + flash_write_func write_buf; + uint32_t buf_addr; + void *buf; }; struct target_s { @@ -215,6 +221,9 @@ void target_add_commands(target *t, const struct command_s *cmds, const char *na void target_add_ram(target *t, uint32_t start, uint32_t len); void target_add_flash(target *t, struct target_flash *f); const char *target_mem_map(target *t); +int target_flash_write_buffered(struct target_flash *f, + uint32_t dest, const void *src, size_t len); +int target_flash_done_buffered(struct target_flash *f); static inline uint32_t target_mem_read32(target *t, uint32_t addr) { diff --git a/src/target.c b/src/target.c index 3ab59bc..266c23e 100644 --- a/src/target.c +++ b/src/target.c @@ -57,6 +57,8 @@ void target_list_free(void) } while (target_list->flash) { void * next = target_list->flash->next; + if (target_list->flash->buf) + free(target_list->flash->buf); free(target_list->flash); target_list->flash = next; } @@ -216,3 +218,51 @@ int target_flash_done(target *t) return 0; } +int target_flash_write_buffered(struct target_flash *f, + uint32_t dest, const void *src, size_t len) +{ + int ret = 0; + + if (f->buf == NULL) { + /* Allocate flash sector buffer */ + f->buf = malloc(f->buf_size); + f->buf_addr = -1; + } + while (len) { + uint32_t offset = dest % f->buf_size; + uint32_t base = dest - offset; + if (base != f->buf_addr) { + if (f->buf_addr != (uint32_t)-1) { + /* Write sector to flash if valid */ + ret |= f->write_buf(f, f->buf_addr, + f->buf, f->buf_size); + } + /* Setup buffer for a new sector */ + f->buf_addr = base; + memset(f->buf, f->erased, f->buf_size); + } + /* Copy chunk into sector buffer */ + size_t sectlen = MIN(f->buf_size - offset, len); + memcpy(f->buf + offset, src, sectlen); + dest += sectlen; + src += sectlen; + len -= sectlen; + } + return ret; +} + +int target_flash_done_buffered(struct target_flash *f) +{ + int ret = 0; + if ((f->buf != NULL) &&(f->buf_addr != (uint32_t)-1)) { + /* Write sector to flash if valid */ + ret = f->write_buf(f, f->buf_addr, f->buf, f->buf_size); + f->buf_addr = -1; + free(f->buf); + f->buf = NULL; + } + + return ret; +} + + -- cgit v1.2.3 From 09b781f1c1593025e6d3157573343f4431f5f5b6 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sat, 4 Apr 2015 19:18:05 -0700 Subject: target: Remove old flash interface. --- src/include/target.h | 7 ------- src/target.c | 10 ---------- 2 files changed, 17 deletions(-) (limited to 'src/include/target.h') diff --git a/src/include/target.h b/src/include/target.h index 96b5506..f86714b 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -182,17 +182,10 @@ struct target_s { uint32_t idcode; /* Target memory map */ - const char *xml_mem_map; char *dyn_mem_map; struct target_ram *ram; struct target_flash *flash; - /* DEPRECATED: Flash memory access functions */ - int (*flash_erase)(target *t, uint32_t addr, size_t len); - int (*flash_write)(target *t, uint32_t dest, - const uint8_t *src, size_t len); - int (*flash_done)(target *t); - /* Host I/O support */ void (*hostio_reply)(target *t, int32_t retcode, uint32_t errcode); diff --git a/src/target.c b/src/target.c index 266c23e..8f33e70 100644 --- a/src/target.c +++ b/src/target.c @@ -131,10 +131,6 @@ static ssize_t map_flash(char *buf, size_t len, struct target_flash *f) const char *target_mem_map(target *t) { - /* Deprecated static const memory map */ - if (t->xml_mem_map) - return t->xml_mem_map; - if (t->dyn_mem_map) return t->dyn_mem_map; @@ -167,9 +163,6 @@ static struct target_flash *flash_for_addr(target *t, uint32_t addr) int target_flash_erase(target *t, uint32_t addr, size_t len) { - if (t->flash_write) - return t->flash_erase(t, addr, len); - int ret = 0; while (len) { struct target_flash *f = flash_for_addr(t, addr); @@ -184,9 +177,6 @@ int target_flash_erase(target *t, uint32_t addr, size_t len) int target_flash_write(target *t, uint32_t dest, const void *src, size_t len) { - if (t->flash_write) - return t->flash_write(t, dest, src, len); - int ret = 0; while (len) { struct target_flash *f = flash_for_addr(t, dest); -- cgit v1.2.3