target_flash: abstract target flash mode/flash preparation
This commit is contained in:
parent
520be57e3d
commit
e72edc0579
|
@ -543,7 +543,6 @@ static void handle_v_packet(char *packet, const size_t plen)
|
|||
uint32_t addr = 0;
|
||||
uint32_t len = 0;
|
||||
int bin;
|
||||
static uint8_t flash_mode = 0;
|
||||
|
||||
if (sscanf(packet, "vAttach;%08" PRIx32, &addr) == 1) {
|
||||
/* Attach to remote target processor */
|
||||
|
@ -631,16 +630,10 @@ static void handle_v_packet(char *packet, const size_t plen)
|
|||
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)
|
||||
gdb_putpacketz("OK");
|
||||
else {
|
||||
flash_mode = 0;
|
||||
target_flash_complete(cur_target);
|
||||
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)
|
||||
gdb_putpacketz("OK");
|
||||
else {
|
||||
flash_mode = 0;
|
||||
target_flash_complete(cur_target);
|
||||
gdb_putpacketz("EFF");
|
||||
}
|
||||
|
||||
} else if (!strcmp(packet, "vFlashDone")) {
|
||||
/* Commit flash operations. */
|
||||
gdb_putpacketz(target_flash_done(cur_target) ? "EFF" : "OK");
|
||||
flash_mode = 0;
|
||||
if (target_flash_complete(cur_target) == 0)
|
||||
gdb_putpacketz("OK");
|
||||
else
|
||||
gdb_putpacketz("EFF");
|
||||
|
||||
} else if (!strcmp(packet, "vStopped")) {
|
||||
if (gdb_needs_detach_notify) {
|
||||
|
|
|
@ -61,7 +61,7 @@ int target_mem_write(target *t, target_addr_t dest, const void *src, size_t len)
|
|||
/* Flash memory access functions */
|
||||
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_done(target *t);
|
||||
int target_flash_complete(target *t);
|
||||
|
||||
/* Register access functions */
|
||||
size_t target_regs_size(target *t);
|
||||
|
|
|
@ -577,7 +577,7 @@ found_targets:
|
|||
map.data, map.size);
|
||||
/* Buffered write cares for padding*/
|
||||
if (!flashed)
|
||||
flashed = target_flash_done(t);
|
||||
flashed = target_flash_complete(t);
|
||||
if (flashed) {
|
||||
DEBUG_WARN("Flashing failed!\n");
|
||||
res = -1;
|
||||
|
|
|
@ -49,8 +49,47 @@ target_flash_s *target_flash_for_addr(target *t, uint32_t addr)
|
|||
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)
|
||||
{
|
||||
if (!t->flash_mode)
|
||||
target_enter_flash_mode(t);
|
||||
|
||||
int ret = 0;
|
||||
while (len) {
|
||||
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)
|
||||
{
|
||||
if (!t->flash_mode)
|
||||
target_enter_flash_mode(t);
|
||||
|
||||
int ret = 0;
|
||||
while (len) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
int tmp = target_flash_done_buffered(f);
|
||||
if (tmp)
|
||||
return tmp;
|
||||
if (f->done) {
|
||||
tmp = f->done(f);
|
||||
if (tmp)
|
||||
return tmp;
|
||||
}
|
||||
ret |= target_flash_done_buffered(f);
|
||||
if (f->done)
|
||||
ret |= f->done(f);
|
||||
}
|
||||
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)
|
||||
|
|
|
@ -115,6 +115,11 @@ struct target_s {
|
|||
/* Recovery functions */
|
||||
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 */
|
||||
unsigned target_options;
|
||||
|
||||
|
|
Loading…
Reference in New Issue