aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGareth McMullin2012-06-27 21:26:08 +1200
committerGareth McMullin2012-06-27 21:26:08 +1200
commit466bb66424a8a44581ae2f9defbe95aa5384c395 (patch)
treeac1ef277e96e3522907596182ce701ca0bd3468b
parent4581da20342c459855a4b585e72746df56e22e26 (diff)
Made cur_target, last_target static in gdb_main.c.
Added target destroy notify mechanism.
-rw-r--r--src/command.c26
-rw-r--r--src/gdb_main.c43
-rw-r--r--src/include/command.h2
-rw-r--r--src/include/target.h21
-rw-r--r--src/platforms/native/platform.h1
-rw-r--r--src/target.c17
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 <stdlib.h>
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;
+}
+