From: David B. <dbr...@us...> - 2009-12-18 20:58:26
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 3f18900b19f49a84ba9df56f2e089c255e610011 (commit) via 013b05f7f813f0d0c15a6bb20068e9423a28bd0d (commit) via 7641934197abbd851127afcb0b7cebc30242f717 (commit) via 12b8c7b89b021c882e68bb0e28863c802fe36ac4 (commit) from 85a4136d0baccf5c3b8f717710584f7faed0ca30 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3f18900b19f49a84ba9df56f2e089c255e610011 Author: David Brownell <dbr...@us...> Date: Fri Dec 18 10:16:52 2009 -0800 NOR FLASH: only erase/unlock whole sectors Much to my surprise, I observed a "flash erase_address ..." command erasing data which I said should not be erased. The issue turns out to be generic NOR flash code which was silently, and rather dangerously, morphing partial-sector references into unrequested whole-sector ones. This patch removes that low-level morphing. If desired, it can and should be done in higher level code. (We might need to fix some stuff in the GDB server code.) Signed-off-by: David Brownell <dbr...@us...> diff --git a/NEWS b/NEWS index 498797b..2d01f00 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,8 @@ Flash Layer: - <bank_name>: reference the bank with its defined name - <driver_name>[.N]: reference the driver's Nth bank New 'nand verify' command to check bank against an image file. + The "flash erase_address" command now rejects partial sectors; + previously it would silently erase extra data. Board, Target, and Interface Configuration Scripts: ARM9 diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index c2ea134..1873dee 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -279,11 +279,13 @@ int default_flash_blank_check(struct flash_bank *bank) return ERROR_OK; } + /* erase given flash region, selects proper bank according to target and address */ static int flash_iterate_address_range(struct target *target, uint32_t addr, uint32_t length, int (*callback)(struct flash_bank *bank, int first, int last)) { struct flash_bank *c; + uint32_t last_addr = addr + length; /* first address AFTER end */ int first = -1; int last = -1; int i; @@ -306,26 +308,52 @@ static int flash_iterate_address_range(struct target *target, uint32_t addr, uin return callback(c, 0, c->num_sectors - 1); } - /* check whether it fits */ + /* check whether it all fits in this bank */ if (addr + length - 1 > c->base + c->size - 1) return ERROR_FLASH_DST_BREAKS_ALIGNMENT; + /** @todo: handle erasures that cross into adjacent banks */ + addr -= c->base; for (i = 0; i < c->num_sectors; i++) { - /* check whether sector overlaps with the given range and is not yet erased */ - if (addr < c->sectors[i].offset + c->sectors[i].size && addr + length > c->sectors[i].offset && c->sectors[i].is_erased != 1) { - /* if first is not set yet then this is the first sector */ - if (first == -1) + struct flash_sector *f = c->sectors + i; + + /* start only on a sector boundary */ + if (first < 0) { + /* is this the first sector? */ + if (addr == f->offset) first = i; - last = i; /* and it is the last one so far in any case */ + else if (addr < f->offset) + break; } + + /* is this (also?) the last sector? */ + if (last_addr == f->offset + f->size) { + last = i; + break; + } + + /* MUST finish on a sector boundary */ + if (last_addr <= f->offset) + break; } - if (first == -1 || last == -1) - return ERROR_OK; + /* invalid start or end address? */ + if (first == -1 || last == -1) { + LOG_ERROR("address range 0x%8.8x .. 0x%8.8x " + "is not sector-aligned", + (unsigned) c->base + addr, + (unsigned) last_addr - 1); + return ERROR_FLASH_DST_BREAKS_ALIGNMENT; + } + /* The NOR driver may trim this range down, based on + * whether or not a given sector is already erased. + * + * REVISIT should *we* trim it... ? + */ return callback(c, first, last); } commit 013b05f7f813f0d0c15a6bb20068e9423a28bd0d Author: David Brownell <dbr...@us...> Date: Fri Dec 18 10:09:35 2009 -0800 Subject: flash fill[bwh] should use bulk i/o It's currently allocating a big buffer but writing it out in units of sizeof(host's pointer) ... sub-optimal. Plus fix a couple minor coding style goofs. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 1e933b2..b5e1b2c 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -534,14 +534,16 @@ COMMAND_HANDLER(handle_flash_fill_command) for (wrote = 0; wrote < (count*wordsize); wrote += cur_size) { - cur_size = MIN((count*wordsize - wrote), sizeof(chunk)); struct flash_bank *bank; + bank = get_flash_bank_by_addr(target, address); if (bank == NULL) { retval = ERROR_FAIL; goto done; } + + cur_size = MIN((count * wordsize - wrote), chunksize); err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size); if (err != ERROR_OK) { @@ -576,7 +578,7 @@ COMMAND_HANDLER(handle_flash_fill_command) duration_elapsed(&bench), duration_kbps(&bench, wrote)); } - done: +done: free(readback); free(chunk); commit 7641934197abbd851127afcb0b7cebc30242f717 Author: David Brownell <dbr...@us...> Date: Fri Dec 18 09:59:40 2009 -0800 stellaris: fix min buffer length checks Word count == size/4; cope. And increase buf_min so it's large enough to cover the overhead in my tests. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index 51fe677..f414ca6 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -826,10 +826,10 @@ static int stellaris_write_block(struct flash_bank *bank, int retval = ERROR_OK; /* power of two, and multiple of word size */ - static const unsigned buf_min = 32; + static const unsigned buf_min = 128; /* for small buffers it's faster not to download an algorithm */ - if (wcount < buf_min) + if (wcount * 4 < buf_min) return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "", @@ -843,11 +843,8 @@ static int stellaris_write_block(struct flash_bank *bank, }; /* plus a buffer big enough for this data */ - if (wcount < buffer_size) { - buffer_size = wcount; - buffer_size += buf_min - 1; - buffer_size &= ~(buf_min - 1); - } + if (wcount * 4 < buffer_size) + buffer_size = wcount * 4; /* memory buffer */ while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) commit 12b8c7b89b021c882e68bb0e28863c802fe36ac4 Author: David Brownell <dbr...@us...> Date: Fri Dec 18 09:53:59 2009 -0800 XScale: better {read,write}_phys() We can actually do the right thing if the MMU is off; save the error message for the phys-but-MMU-enabled path, which is what isn't yet supported. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/xscale.c b/src/target/xscale.c index 4cf5aeb..f1afc71 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -1905,7 +1905,13 @@ static int xscale_read_memory(struct target *target, uint32_t address, static int xscale_read_phys_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { - /** \todo: provide a non-stub implementtion of this routine. */ + struct xscale_common *xscale = target_to_xscale(target); + + /* with MMU inactive, there are only physical addresses */ + if (!xscale->armv4_5_mmu.mmu_enabled) + return xscale_read_memory(target, address, size, count, buffer); + + /** \todo: provide a non-stub implementation of this routine. */ LOG_ERROR("%s: %s is not implemented. Disable MMU?", target_name(target), __func__); return ERROR_FAIL; @@ -1992,7 +1998,13 @@ static int xscale_write_memory(struct target *target, uint32_t address, static int xscale_write_phys_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { - /** \todo: provide a non-stub implementtion of this routine. */ + struct xscale_common *xscale = target_to_xscale(target); + + /* with MMU inactive, there are only physical addresses */ + if (!xscale->armv4_5_mmu.mmu_enabled) + return xscale_read_memory(target, address, size, count, buffer); + + /** \todo: provide a non-stub implementation of this routine. */ LOG_ERROR("%s: %s is not implemented. Disable MMU?", target_name(target), __func__); return ERROR_FAIL; ----------------------------------------------------------------------- Summary of changes: NEWS | 2 ++ src/flash/nor/core.c | 44 ++++++++++++++++++++++++++++++++++++-------- src/flash/nor/stellaris.c | 11 ++++------- src/flash/nor/tcl.c | 6 ++++-- src/target/xscale.c | 16 ++++++++++++++-- 5 files changed, 60 insertions(+), 19 deletions(-) hooks/post-receive -- Main OpenOCD repository |