Made cur_target, last_target static in gdb_main.c.

Added target destroy notify mechanism.
This commit is contained in:
Gareth McMullin 2012-06-27 21:26:08 +12:00
parent 4581da2034
commit 466bb66424
6 changed files with 75 additions and 35 deletions

View File

@ -36,11 +36,11 @@
#include "adiv5.h" #include "adiv5.h"
static bool cmd_version(void); 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_jtag_scan(void);
static bool cmd_swdp_scan(void); static bool cmd_swdp_scan(void);
static bool cmd_targets(void); static bool cmd_targets(target *t);
static bool cmd_morse(void); static bool cmd_morse(void);
#ifdef PLATFORM_HAS_TRACESWO #ifdef PLATFORM_HAS_TRACESWO
static bool cmd_traceswo(void); 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; struct target_command_s *tc;
const struct command_s *c; const struct command_s *c;
@ -83,16 +83,16 @@ int command_process(char *cmd)
* So 'mon ver' will match 'monitor version' * So 'mon ver' will match 'monitor version'
*/ */
if(!strncmp(argv[0], c->cmd, strlen(argv[0]))) 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; 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++) for(c = tc->cmds; c->cmd; c++)
if(!strncmp(argv[0], c->cmd, strlen(argv[0]))) if(!strncmp(argv[0], c->cmd, strlen(argv[0])))
return !c->handler(cur_target, argc, argv); return !c->handler(t, argc, argv);
return -1; return -1;
} }
@ -107,7 +107,7 @@ bool cmd_version(void)
return true; return true;
} }
bool cmd_help(void) bool cmd_help(target *t)
{ {
struct target_command_s *tc; struct target_command_s *tc;
const struct command_s *c; const struct command_s *c;
@ -116,10 +116,10 @@ bool cmd_help(void)
for(c = cmd_list; c->cmd; c++) for(c = cmd_list; c->cmd; c++)
gdb_outf("\t%s -- %s\n", c->cmd, c->help); gdb_outf("\t%s -- %s\n", c->cmd, c->help);
if (!cur_target) if (!t)
return -1; 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); gdb_outf("%s specific commands:\n", tc->specific_name);
for(c = tc->cmds; c->cmd; c++) for(c = tc->cmds; c->cmd; c++)
gdb_outf("\t%s -- %s\n", c->cmd, c->help); 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].ir_len, jtag_devs[i].idcode,
jtag_devs[i].descr); jtag_devs[i].descr);
gdb_out("\n"); gdb_out("\n");
cmd_targets(); cmd_targets(NULL);
return true; return true;
} }
@ -163,12 +163,12 @@ bool cmd_swdp_scan(void)
gdb_outf("SW-DP detected IDCODE: 0x%08X\n", adiv5_dp_list->idcode); gdb_outf("SW-DP detected IDCODE: 0x%08X\n", adiv5_dp_list->idcode);
cmd_targets(); cmd_targets(NULL);
return true; return true;
} }
bool cmd_targets(void) bool cmd_targets(target *cur_target)
{ {
struct target_s *t; struct target_s *t;
int i; int i;

View File

@ -54,9 +54,21 @@
static unsigned char pbuf[BUF_SIZE]; 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_q_packet(char *packet, int len);
static void handle_v_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 void
gdb_main(void) gdb_main(void)
{ {
@ -207,8 +219,8 @@ gdb_main(void)
if(cur_target) if(cur_target)
target_reset(cur_target); target_reset(cur_target);
else if(last_target) { else if(last_target) {
cur_target = last_target; cur_target = target_attach(last_target,
target_attach(cur_target); gdb_target_destroy_callback);
target_reset(cur_target); target_reset(cur_target);
} }
break; break;
@ -330,7 +342,7 @@ handle_q_packet(char *packet, int len)
unhexify(data, packet+6, datalen); unhexify(data, packet+6, datalen);
data[datalen] = 0; /* add terminating null */ data[datalen] = 0; /* add terminating null */
int c = command_process(data); int c = command_process(cur_target, data);
if(c < 0) if(c < 0)
gdb_putpacketz(""); gdb_putpacketz("");
else if(c == 0) else if(c == 0)
@ -346,8 +358,8 @@ handle_q_packet(char *packet, int len)
/* Read target XML memory map */ /* Read target XML memory map */
if((!cur_target) && last_target) { if((!cur_target) && last_target) {
/* Attach to last target if detached. */ /* Attach to last target if detached. */
cur_target = last_target; cur_target = target_attach(last_target,
target_attach(cur_target); gdb_target_destroy_callback);
} }
if((!cur_target) || (!cur_target->xml_mem_map)) { if((!cur_target) || (!cur_target->xml_mem_map)) {
gdb_putpacketz("E01"); gdb_putpacketz("E01");
@ -359,8 +371,8 @@ handle_q_packet(char *packet, int len)
/* Read target description */ /* Read target description */
if((!cur_target) && last_target) { if((!cur_target) && last_target) {
/* Attach to last target if detached. */ /* Attach to last target if detached. */
cur_target = last_target; cur_target = target_attach(last_target,
target_attach(cur_target); gdb_target_destroy_callback);
} }
if((!cur_target) || (!cur_target->tdesc)) { if((!cur_target) || (!cur_target->tdesc)) {
gdb_putpacketz("E01"); 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)); 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 static void
@ -390,8 +405,8 @@ handle_v_packet(char *packet, int plen)
uint32_t i; uint32_t i;
for(t = target_list, i = 1; t; t = t->next, i++) for(t = target_list, i = 1; t; t = t->next, i++)
if(i == addr) { if(i == addr) {
cur_target = t; cur_target = target_attach(t,
target_attach(t); gdb_target_destroy_callback);
gdb_putpacketz("T05"); gdb_putpacketz("T05");
break; break;
} }
@ -404,8 +419,8 @@ handle_v_packet(char *packet, int plen)
target_reset(cur_target); target_reset(cur_target);
gdb_putpacketz("T05"); gdb_putpacketz("T05");
} else if(last_target) { } else if(last_target) {
cur_target = last_target; cur_target = target_attach(last_target,
target_attach(cur_target); gdb_target_destroy_callback);
target_reset(cur_target); target_reset(cur_target);
gdb_putpacketz("T05"); gdb_putpacketz("T05");
} else gdb_putpacketz("E01"); } else gdb_putpacketz("E01");
@ -440,7 +455,9 @@ handle_v_packet(char *packet, int plen)
gdb_putpacketz("OK"); gdb_putpacketz("OK");
flash_mode = 0; flash_mode = 0;
} else } else {
DEBUG("*** Unsupported packet: %s\n", packet);
gdb_putpacket("", 0); gdb_putpacket("", 0);
}
} }

View File

@ -24,7 +24,7 @@
#include "general.h" #include "general.h"
#include "target.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); typedef bool (*cmd_handler)(target *t, int argc, const char **argv);
struct command_s { struct command_s {

View File

@ -27,9 +27,19 @@
typedef struct target_s target; 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 */ /* Halt/resume functions */
#define target_attach(target) \ target *target_attach(target *t, target_destroy_callback destroy_cb);
(target)->attach(target)
#define target_detach(target) \ #define target_detach(target) \
(target)->detach(target) (target)->detach(target)
@ -37,7 +47,6 @@ typedef struct target_s target;
#define target_check_error(target) \ #define target_check_error(target) \
(target)->check_error(target) (target)->check_error(target)
/* Memory access functions */ /* Memory access functions */
#define target_mem_read_words(target, dest, src, len) \ #define target_mem_read_words(target, dest, src, len) \
(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) \ #define target_flash_write(target, dest, src, len) \
(target)->flash_write((target), (dest), (src), (len)) (target)->flash_write((target), (dest), (src), (len))
struct target_s { struct target_s {
/* Notify controlling debugger if target is lost */
target_destroy_callback destroy_callback;
/* Attach/Detach funcitons */ /* Attach/Detach funcitons */
void (*attach)(struct target_s *target); void (*attach)(struct target_s *target);
void (*detach)(struct target_s *target); void (*detach)(struct target_s *target);
@ -174,7 +187,7 @@ struct target_command_s {
struct target_command_s *next; struct target_command_s *next;
}; };
extern target *target_list, *cur_target, *last_target; extern target *target_list;
target *target_new(unsigned size); target *target_new(unsigned size);
void target_list_free(void); void target_list_free(void);

View File

@ -127,7 +127,6 @@ extern const char *morse_msg;
else gdb_putpacketz("EFF"); \ else gdb_putpacketz("EFF"); \
running_status = 0; \ running_status = 0; \
target_list_free(); \ target_list_free(); \
cur_target = last_target = NULL; \
morse("TARGET LOST.", 1); \ morse("TARGET LOST.", 1); \
longjmp(fatal_error_jmpbuf, (error)); \ longjmp(fatal_error_jmpbuf, (error)); \
} }

View File

@ -24,8 +24,6 @@
#include <stdlib.h> #include <stdlib.h>
target *target_list = NULL; target *target_list = NULL;
target *cur_target = NULL;
target *last_target = NULL;
target *target_new(unsigned size) target *target_new(unsigned size)
{ {
@ -42,6 +40,8 @@ void target_list_free(void)
while(target_list) { while(target_list) {
target *t = target_list->next; target *t = target_list->next;
if (target_list->destroy_callback)
target_list->destroy_callback(target_list);
while (target_list->commands) { while (target_list->commands) {
tc = target_list->commands->next; tc = target_list->commands->next;
free(target_list->commands); free(target_list->commands);
@ -50,7 +50,6 @@ void target_list_free(void)
free(target_list); free(target_list);
target_list = t; target_list = t;
} }
last_target = cur_target = NULL;
} }
void target_add_commands(target *t, const struct command_s *cmds, const char *name) 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; 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;
}