target_flash: abstract target flash mode/flash preparation

This commit is contained in:
Rafael Silva 2022-08-22 11:21:41 +01:00 committed by Rachel Mant
parent 520be57e3d
commit e72edc0579
5 changed files with 65 additions and 23 deletions

View File

@ -543,7 +543,6 @@ static void handle_v_packet(char *packet, const size_t plen)
uint32_t addr = 0; uint32_t addr = 0;
uint32_t len = 0; uint32_t len = 0;
int bin; int bin;
static uint8_t flash_mode = 0;
if (sscanf(packet, "vAttach;%08" PRIx32, &addr) == 1) { if (sscanf(packet, "vAttach;%08" PRIx32, &addr) == 1) {
/* Attach to remote target processor */ /* Attach to remote target processor */
@ -631,16 +630,10 @@ static void handle_v_packet(char *packet, const size_t plen)
return; return;
} }
if (!flash_mode) {
/* Reset target if first flash command! */
/* This saves us if we're interrupted in IRQ context */
target_reset(cur_target);
flash_mode = 1;
}
if (target_flash_erase(cur_target, addr, len) == 0) if (target_flash_erase(cur_target, addr, len) == 0)
gdb_putpacketz("OK"); gdb_putpacketz("OK");
else { else {
flash_mode = 0; target_flash_complete(cur_target);
gdb_putpacketz("EFF"); gdb_putpacketz("EFF");
} }
@ -651,14 +644,16 @@ static void handle_v_packet(char *packet, const size_t plen)
if (cur_target && target_flash_write(cur_target, addr, (void*)packet + bin, count) == 0) if (cur_target && target_flash_write(cur_target, addr, (void*)packet + bin, count) == 0)
gdb_putpacketz("OK"); gdb_putpacketz("OK");
else { else {
flash_mode = 0; target_flash_complete(cur_target);
gdb_putpacketz("EFF"); gdb_putpacketz("EFF");
} }
} else if (!strcmp(packet, "vFlashDone")) { } else if (!strcmp(packet, "vFlashDone")) {
/* Commit flash operations. */ /* Commit flash operations. */
gdb_putpacketz(target_flash_done(cur_target) ? "EFF" : "OK"); if (target_flash_complete(cur_target) == 0)
flash_mode = 0; gdb_putpacketz("OK");
else
gdb_putpacketz("EFF");
} else if (!strcmp(packet, "vStopped")) { } else if (!strcmp(packet, "vStopped")) {
if (gdb_needs_detach_notify) { if (gdb_needs_detach_notify) {

View File

@ -61,7 +61,7 @@ int target_mem_write(target *t, target_addr_t dest, const void *src, size_t len)
/* Flash memory access functions */ /* Flash memory access functions */
int target_flash_erase(target *t, target_addr_t addr, size_t len); int target_flash_erase(target *t, target_addr_t addr, size_t len);
int target_flash_write(target *t, target_addr_t dest, const void *src, size_t len); int target_flash_write(target *t, target_addr_t dest, const void *src, size_t len);
int target_flash_done(target *t); int target_flash_complete(target *t);
/* Register access functions */ /* Register access functions */
size_t target_regs_size(target *t); size_t target_regs_size(target *t);

View File

@ -577,7 +577,7 @@ found_targets:
map.data, map.size); map.data, map.size);
/* Buffered write cares for padding*/ /* Buffered write cares for padding*/
if (!flashed) if (!flashed)
flashed = target_flash_done(t); flashed = target_flash_complete(t);
if (flashed) { if (flashed) {
DEBUG_WARN("Flashing failed!\n"); DEBUG_WARN("Flashing failed!\n");
res = -1; res = -1;

View File

@ -49,8 +49,47 @@ target_flash_s *target_flash_for_addr(target *t, uint32_t addr)
return NULL; return NULL;
} }
static int target_enter_flash_mode(target *t)
{
if (t->flash_mode)
return 0;
int ret = 0;
if (t->enter_flash_mode)
ret = t->enter_flash_mode(t);
else
/* Reset target on flash command */
/* This saves us if we're interrupted in IRQ context */
target_reset(t);
if (ret == 0)
t->flash_mode = true;
return ret;
}
static int target_exit_flash_mode(target *t)
{
if (!t->flash_mode)
return 0;
int ret = 0;
if (t->exit_flash_mode)
ret = t->exit_flash_mode(t);
else
/* Reset target to known state when done flashing */
target_reset(t);
t->flash_mode = false;
return ret;
}
int target_flash_erase(target *t, target_addr_t addr, size_t len) int target_flash_erase(target *t, target_addr_t addr, size_t len)
{ {
if (!t->flash_mode)
target_enter_flash_mode(t);
int ret = 0; int ret = 0;
while (len) { while (len) {
target_flash_s *f = target_flash_for_addr(t, addr); target_flash_s *f = target_flash_for_addr(t, addr);
@ -72,6 +111,9 @@ int target_flash_erase(target *t, target_addr_t addr, size_t len)
int target_flash_write(target *t, target_addr_t dest, const void *src, size_t len) int target_flash_write(target *t, target_addr_t dest, const void *src, size_t len)
{ {
if (!t->flash_mode)
target_enter_flash_mode(t);
int ret = 0; int ret = 0;
while (len) { while (len) {
target_flash_s *f = target_flash_for_addr(t, dest); target_flash_s *f = target_flash_for_addr(t, dest);
@ -92,19 +134,19 @@ int target_flash_write(target *t, target_addr_t dest, const void *src, size_t le
return ret; return ret;
} }
int target_flash_done(target *t) int target_flash_complete(target *t)
{ {
if (!t->flash_mode)
return -1;
int ret = 0;
for (target_flash_s *f = t->flash; f; f = f->next) { for (target_flash_s *f = t->flash; f; f = f->next) {
int tmp = target_flash_done_buffered(f); ret |= target_flash_done_buffered(f);
if (tmp) if (f->done)
return tmp; ret |= f->done(f);
if (f->done) {
tmp = f->done(f);
if (tmp)
return tmp;
}
} }
return 0; target_exit_flash_mode(t);
return ret;
} }
int target_flash_write_buffered(target_flash_s *f, target_addr_t dest, const void *src, size_t len) int target_flash_write_buffered(target_flash_s *f, target_addr_t dest, const void *src, size_t len)

View File

@ -115,6 +115,11 @@ struct target_s {
/* Recovery functions */ /* Recovery functions */
bool (*mass_erase)(target *t); bool (*mass_erase)(target *t);
/* Flash functions */
int (*enter_flash_mode)(target *t);
int (*exit_flash_mode)(target *t);
bool flash_mode;
/* target-defined options */ /* target-defined options */
unsigned target_options; unsigned target_options;