aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGareth McMullin2015-03-24 20:45:59 -0700
committerGareth McMullin2015-04-03 21:20:01 -0700
commit7202db586038843d1d4f01403ce6e1285ac3520c (patch)
treee0589ce234ce6975e395ee959b6c64bfebb04472
parent691d21989a6957be728635fe8b56720c21758a3f (diff)
Add new functions to wrap flash driver erase/write/done operations.
-rw-r--r--src/include/target.h12
-rw-r--r--src/target.c54
2 files changed, 58 insertions, 8 deletions
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;
+}
+