fix flash bank auto_probe() fail with multiple targets

get_flash_bank_by_addr() iterates through all flash banks
trying to auto_probe() every bank, even if bank can belongs to
target other than requested, and this other target can be
in non-halted state, which leads to error message and
operation abort.
  Same situation in gdb_new_connection() and gdb_memory_map():
get_flash_bank_by_num() tries to auto_probe() requested bank,
so first get bank by get_flash_bank_by_num_noprobe(), check
if it belongs to current connection's target and skip
get_flash_bank_by_num() (actually autoprobing) if not.

Change-Id: I48b3f93dddcd9283394f14ad2de3248397c75ab3
Signed-off-by: Sergey A. Borshch <sb-sf@users.sourceforge.net>
Reviewed-on: http://openocd.zylin.com/1813
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
This commit is contained in:
Sergey A. Borshch 2013-11-22 17:27:40 +02:00 committed by Andreas Fritiofson
parent 255301fb50
commit 5175f8be33
2 changed files with 11 additions and 3 deletions

View File

@ -232,6 +232,9 @@ int get_flash_bank_by_addr(struct target *target,
/* cycle through bank list */ /* cycle through bank list */
for (c = flash_banks; c; c = c->next) { for (c = flash_banks; c; c = c->next) {
if (c->target != target)
continue;
int retval; int retval;
retval = c->driver->auto_probe(c); retval = c->driver->auto_probe(c);
@ -240,7 +243,7 @@ int get_flash_bank_by_addr(struct target *target,
return retval; return retval;
} }
/* check whether address belongs to this flash bank */ /* check whether address belongs to this flash bank */
if ((addr >= c->base) && (addr <= c->base + (c->size - 1)) && target == c->target) { if ((addr >= c->base) && (addr <= c->base + (c->size - 1))) {
*result_bank = c; *result_bank = c;
return ERROR_OK; return ERROR_OK;
} }

View File

@ -957,6 +957,9 @@ static int gdb_new_connection(struct connection *connection)
int i; int i;
for (i = 0; i < flash_get_bank_count(); i++) { for (i = 0; i < flash_get_bank_count(); i++) {
struct flash_bank *p; struct flash_bank *p;
p = get_flash_bank_by_num_noprobe(i);
if (p->target != gdb_service->target)
continue;
retval = get_flash_bank_by_num(i, &p); retval = get_flash_bank_by_num(i, &p);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target " \ LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target " \
@ -1732,14 +1735,16 @@ static int gdb_memory_map(struct connection *connection,
banks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count()); banks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count());
for (i = 0; i < flash_get_bank_count(); i++) { for (i = 0; i < flash_get_bank_count(); i++) {
p = get_flash_bank_by_num_noprobe(i);
if (p->target != target)
continue;
retval = get_flash_bank_by_num(i, &p); retval = get_flash_bank_by_num(i, &p);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
free(banks); free(banks);
gdb_error(connection, retval); gdb_error(connection, retval);
return retval; return retval;
} }
if (p->target == target) banks[target_flash_banks++] = p;
banks[target_flash_banks++] = p;
} }
qsort(banks, target_flash_banks, sizeof(struct flash_bank *), qsort(banks, target_flash_banks, sizeof(struct flash_bank *),