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 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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
target_exit_flash_mode(t);
|
||||||
return 0;
|
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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue