From 466bb66424a8a44581ae2f9defbe95aa5384c395 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Wed, 27 Jun 2012 21:26:08 +1200 Subject: [PATCH] Made cur_target, last_target static in gdb_main.c. Added target destroy notify mechanism. --- src/command.c | 26 ++++++++++---------- src/gdb_main.c | 43 +++++++++++++++++++++++---------- src/include/command.h | 2 +- src/include/target.h | 21 +++++++++++++--- src/platforms/native/platform.h | 1 - src/target.c | 17 ++++++++++--- 6 files changed, 75 insertions(+), 35 deletions(-) diff --git a/src/command.c b/src/command.c index 24227f3..241f877 100644 --- a/src/command.c +++ b/src/command.c @@ -36,11 +36,11 @@ #include "adiv5.h" static bool cmd_version(void); -static bool cmd_help(void); +static bool cmd_help(target *t); static bool cmd_jtag_scan(void); static bool cmd_swdp_scan(void); -static bool cmd_targets(void); +static bool cmd_targets(target *t); static bool cmd_morse(void); #ifdef PLATFORM_HAS_TRACESWO static bool cmd_traceswo(void); @@ -60,7 +60,7 @@ const struct command_s cmd_list[] = { }; -int command_process(char *cmd) +int command_process(target *t, char *cmd) { struct target_command_s *tc; const struct command_s *c; @@ -83,16 +83,16 @@ int command_process(char *cmd) * So 'mon ver' will match 'monitor version' */ if(!strncmp(argv[0], c->cmd, strlen(argv[0]))) - return !c->handler(cur_target, argc, argv); + return !c->handler(t, argc, argv); } - if (!cur_target) + if (!t) return -1; - for (tc = cur_target->commands; tc; tc = tc->next) + for (tc = t->commands; tc; tc = tc->next) for(c = tc->cmds; c->cmd; c++) if(!strncmp(argv[0], c->cmd, strlen(argv[0]))) - return !c->handler(cur_target, argc, argv); + return !c->handler(t, argc, argv); return -1; } @@ -107,7 +107,7 @@ bool cmd_version(void) return true; } -bool cmd_help(void) +bool cmd_help(target *t) { struct target_command_s *tc; const struct command_s *c; @@ -116,10 +116,10 @@ bool cmd_help(void) for(c = cmd_list; c->cmd; c++) gdb_outf("\t%s -- %s\n", c->cmd, c->help); - if (!cur_target) + if (!t) return -1; - for (tc = cur_target->commands; tc; tc = tc->next) { + for (tc = t->commands; tc; tc = tc->next) { gdb_outf("%s specific commands:\n", tc->specific_name); for(c = tc->cmds; c->cmd; c++) gdb_outf("\t%s -- %s\n", c->cmd, c->help); @@ -148,7 +148,7 @@ bool cmd_jtag_scan(void) jtag_devs[i].ir_len, jtag_devs[i].idcode, jtag_devs[i].descr); gdb_out("\n"); - cmd_targets(); + cmd_targets(NULL); return true; } @@ -163,12 +163,12 @@ bool cmd_swdp_scan(void) gdb_outf("SW-DP detected IDCODE: 0x%08X\n", adiv5_dp_list->idcode); - cmd_targets(); + cmd_targets(NULL); return true; } -bool cmd_targets(void) +bool cmd_targets(target *cur_target) { struct target_s *t; int i; diff --git a/src/gdb_main.c b/src/gdb_main.c index dc00e2e..c2adba9 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -54,9 +54,21 @@ static unsigned char pbuf[BUF_SIZE]; +static target *cur_target; +static target *last_target; + static void handle_q_packet(char *packet, int len); static void handle_v_packet(char *packet, int len); +static void gdb_target_destroy_callback(target *t) +{ + if (cur_target == t) + cur_target = NULL; + + if (last_target == t) + last_target = NULL; +} + void gdb_main(void) { @@ -207,8 +219,8 @@ gdb_main(void) if(cur_target) target_reset(cur_target); else if(last_target) { - cur_target = last_target; - target_attach(cur_target); + cur_target = target_attach(last_target, + gdb_target_destroy_callback); target_reset(cur_target); } break; @@ -330,7 +342,7 @@ handle_q_packet(char *packet, int len) unhexify(data, packet+6, datalen); data[datalen] = 0; /* add terminating null */ - int c = command_process(data); + int c = command_process(cur_target, data); if(c < 0) gdb_putpacketz(""); else if(c == 0) @@ -346,8 +358,8 @@ handle_q_packet(char *packet, int len) /* Read target XML memory map */ if((!cur_target) && last_target) { /* Attach to last target if detached. */ - cur_target = last_target; - target_attach(cur_target); + cur_target = target_attach(last_target, + gdb_target_destroy_callback); } if((!cur_target) || (!cur_target->xml_mem_map)) { gdb_putpacketz("E01"); @@ -359,8 +371,8 @@ handle_q_packet(char *packet, int len) /* Read target description */ if((!cur_target) && last_target) { /* Attach to last target if detached. */ - cur_target = last_target; - target_attach(cur_target); + cur_target = target_attach(last_target, + gdb_target_destroy_callback); } if((!cur_target) || (!cur_target->tdesc)) { gdb_putpacketz("E01"); @@ -374,7 +386,10 @@ handle_q_packet(char *packet, int len) } gdb_putpacket_f("C%lx", generic_crc32(cur_target, addr, alen)); - } else gdb_putpacket("", 0); + } else { + DEBUG("*** Unsupported packet: %s\n", packet); + gdb_putpacket("", 0); + } } static void @@ -390,8 +405,8 @@ handle_v_packet(char *packet, int plen) uint32_t i; for(t = target_list, i = 1; t; t = t->next, i++) if(i == addr) { - cur_target = t; - target_attach(t); + cur_target = target_attach(t, + gdb_target_destroy_callback); gdb_putpacketz("T05"); break; } @@ -404,8 +419,8 @@ handle_v_packet(char *packet, int plen) target_reset(cur_target); gdb_putpacketz("T05"); } else if(last_target) { - cur_target = last_target; - target_attach(cur_target); + cur_target = target_attach(last_target, + gdb_target_destroy_callback); target_reset(cur_target); gdb_putpacketz("T05"); } else gdb_putpacketz("E01"); @@ -440,7 +455,9 @@ handle_v_packet(char *packet, int plen) gdb_putpacketz("OK"); flash_mode = 0; - } else + } else { + DEBUG("*** Unsupported packet: %s\n", packet); gdb_putpacket("", 0); + } } diff --git a/src/include/command.h b/src/include/command.h index a44ed13..32b0d7b 100644 --- a/src/include/command.h +++ b/src/include/command.h @@ -24,7 +24,7 @@ #include "general.h" #include "target.h" -int command_process(char *cmd); +int command_process(target *t, char *cmd); typedef bool (*cmd_handler)(target *t, int argc, const char **argv); struct command_s { diff --git a/src/include/target.h b/src/include/target.h index dc602aa..4a702a1 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -27,9 +27,19 @@ typedef struct target_s target; +/* The destroy callback function will be called by target_list_free() just + * before the target is free'd. This may be because we're scanning for new + * targets, or because of a communication failure. The target data may + * be assumed to be intact, but the communication medium may not be available, + * so access methods shouldn't be called. + * + * The callback is installed by target_attach() and only removed by attaching + * with a different callback. It remains intact after target_detach(). + */ +typedef void (*target_destroy_callback)(target *t); + /* Halt/resume functions */ -#define target_attach(target) \ - (target)->attach(target) +target *target_attach(target *t, target_destroy_callback destroy_cb); #define target_detach(target) \ (target)->detach(target) @@ -37,7 +47,6 @@ typedef struct target_s target; #define target_check_error(target) \ (target)->check_error(target) - /* Memory access functions */ #define target_mem_read_words(target, dest, src, len) \ (target)->mem_read_words((target), (dest), (src), (len)) @@ -108,7 +117,11 @@ typedef struct target_s target; #define target_flash_write(target, dest, src, len) \ (target)->flash_write((target), (dest), (src), (len)) + struct target_s { + /* Notify controlling debugger if target is lost */ + target_destroy_callback destroy_callback; + /* Attach/Detach funcitons */ void (*attach)(struct target_s *target); void (*detach)(struct target_s *target); @@ -174,7 +187,7 @@ struct target_command_s { struct target_command_s *next; }; -extern target *target_list, *cur_target, *last_target; +extern target *target_list; target *target_new(unsigned size); void target_list_free(void); diff --git a/src/platforms/native/platform.h b/src/platforms/native/platform.h index 2258434..1c97c9c 100644 --- a/src/platforms/native/platform.h +++ b/src/platforms/native/platform.h @@ -127,7 +127,6 @@ extern const char *morse_msg; else gdb_putpacketz("EFF"); \ running_status = 0; \ target_list_free(); \ - cur_target = last_target = NULL; \ morse("TARGET LOST.", 1); \ longjmp(fatal_error_jmpbuf, (error)); \ } diff --git a/src/target.c b/src/target.c index 4f2917f..5189929 100644 --- a/src/target.c +++ b/src/target.c @@ -24,8 +24,6 @@ #include target *target_list = NULL; -target *cur_target = NULL; -target *last_target = NULL; target *target_new(unsigned size) { @@ -42,6 +40,8 @@ void target_list_free(void) while(target_list) { target *t = target_list->next; + if (target_list->destroy_callback) + target_list->destroy_callback(target_list); while (target_list->commands) { tc = target_list->commands->next; free(target_list->commands); @@ -50,7 +50,6 @@ void target_list_free(void) free(target_list); target_list = t; } - last_target = cur_target = NULL; } void target_add_commands(target *t, const struct command_s *cmds, const char *name) @@ -67,3 +66,15 @@ void target_add_commands(target *t, const struct command_s *cmds, const char *na tc->next = NULL; } +target *target_attach(target *t, target_destroy_callback destroy_cb) +{ + if (t->destroy_callback) + t->destroy_callback(t); + + t->destroy_callback = destroy_cb; + + t->attach(t); + + return t; +} +