diff options
author | Øyvind Harboe <oyvind.harboe@zylin.com> | 2010-11-22 11:16:40 +0100 |
---|---|---|
committer | Øyvind Harboe <oyvind.harboe@zylin.com> | 2010-11-22 11:16:40 +0100 |
commit | 8902789f0de78f52d74e467017a064dcc568b66b (patch) | |
tree | c1d6a43589dae4e0499a0111546350ab53b5b6eb | |
parent | 17634b3760c58239f37d75113425e50fd3756470 (diff) | |
download | openocd+libswd-8902789f0de78f52d74e467017a064dcc568b66b.tar.gz openocd+libswd-8902789f0de78f52d74e467017a064dcc568b66b.tar.bz2 openocd+libswd-8902789f0de78f52d74e467017a064dcc568b66b.tar.xz openocd+libswd-8902789f0de78f52d74e467017a064dcc568b66b.zip |
flash: iterating over an address range now handles multiple banks
e.g. flash erase_address now works across an address
range that spans multiple flash chips.
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
-rw-r--r-- | src/flash/nor/core.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index da73bf64..ff467d3d 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -379,7 +379,7 @@ int default_flash_blank_check(struct flash_bank *bank) * sectors will be added to the range, and that reason string is used when * warning about those additions. */ -static int flash_iterate_address_range(struct target *target, +static int flash_iterate_address_range_inner(struct target *target, char *pad_reason, uint32_t addr, uint32_t length, int (*callback)(struct flash_bank *bank, int first, int last)) { @@ -498,6 +498,43 @@ static int flash_iterate_address_range(struct target *target, return callback(c, first, last); } +/* The inner fn only handles a single bank, we could be spanning + * multiple chips. + */ +static int flash_iterate_address_range(struct target *target, + char *pad_reason, uint32_t addr, uint32_t length, + int (*callback)(struct flash_bank *bank, int first, int last)) +{ + struct flash_bank *c; + int retval = ERROR_OK; + + /* Danger! zero-length iterations means entire bank! */ + do + { + retval = get_flash_bank_by_addr(target, addr, true, &c); + if (retval != ERROR_OK) + return retval; + + uint32_t cur_length = length; + /* check whether it all fits in this bank */ + if (addr + length - 1 > c->base + c->size - 1) + { + LOG_DEBUG("iterating over more than one flash bank."); + cur_length = c->base + c->size - addr; + } + retval = flash_iterate_address_range_inner(target, + pad_reason, addr, cur_length, + callback); + if (retval != ERROR_OK) + break; + + length -= cur_length; + addr += cur_length; + } while (length > 0); + + return retval; +} + int flash_erase_address_range(struct target *target, bool pad, uint32_t addr, uint32_t length) { |