diff --git a/src/gdb_main.c b/src/gdb_main.c index 124fbd2c..7833980a 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -47,8 +47,9 @@ static void handle_q_packet(char *packet, int len); static void handle_v_packet(char *packet, int len); static void handle_z_packet(char *packet, int len); -static void gdb_target_destroy_callback(target *t) +static void gdb_target_destroy_callback(struct target_controller *tc, target *t) { + (void)tc; if (cur_target == t) cur_target = NULL; @@ -56,6 +57,18 @@ static void gdb_target_destroy_callback(target *t) last_target = NULL; } +static void gdb_target_printf(struct target_controller *tc, + const char *fmt, va_list ap) +{ + (void)tc; + gdb_voutf(fmt, ap); +} + +static struct target_controller gdb_controller = { + .destroy_callback = gdb_target_destroy_callback, + .printf = gdb_target_printf, +}; + void gdb_main(void) { @@ -227,7 +240,7 @@ gdb_main(void) target_reset(cur_target); else if(last_target) { cur_target = target_attach(last_target, - gdb_target_destroy_callback); + &gdb_controller); target_reset(cur_target); } break; @@ -323,7 +336,7 @@ handle_q_packet(char *packet, int len) if((!cur_target) && last_target) { /* Attach to last target if detached. */ cur_target = target_attach(last_target, - gdb_target_destroy_callback); + &gdb_controller); } if (!cur_target) { gdb_putpacketz("E01"); @@ -336,7 +349,7 @@ handle_q_packet(char *packet, int len) if((!cur_target) && last_target) { /* Attach to last target if detached. */ cur_target = target_attach(last_target, - gdb_target_destroy_callback); + &gdb_controller); } if (!cur_target) { gdb_putpacketz("E01"); @@ -365,7 +378,7 @@ handle_v_packet(char *packet, int plen) if (sscanf(packet, "vAttach;%08lx", &addr) == 1) { /* Attach to remote target processor */ - cur_target = target_attach_n(addr, gdb_target_destroy_callback); + cur_target = target_attach_n(addr, &gdb_controller); if(cur_target) gdb_putpacketz("T05"); else @@ -378,7 +391,7 @@ handle_v_packet(char *packet, int plen) gdb_putpacketz("T05"); } else if(last_target) { cur_target = target_attach(last_target, - gdb_target_destroy_callback); + &gdb_controller); /* If we were able to attach to the target again */ if (cur_target) { diff --git a/src/include/target.h b/src/include/target.h index 182f1c6d..ac9b844c 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -33,20 +33,14 @@ int jtag_scan(const uint8_t *lrlens); bool target_foreach(void (*cb)(int i, target *t, void *context), void *context); void target_list_free(void); -/* 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); +struct target_controller { + void (*destroy_callback)(struct target_controller *, target *t); + void (*printf)(struct target_controller *, const char *fmt, va_list); +}; /* Halt/resume functions */ -target *target_attach(target *t, target_destroy_callback destroy_cb); -target *target_attach_n(int n, target_destroy_callback destroy_cb); +target *target_attach(target *t, struct target_controller *); +target *target_attach_n(int n, struct target_controller *); void target_detach(target *t); bool target_check_error(target *t); bool target_attached(target *t); diff --git a/src/target.c b/src/target.c index 94018156..235bbb97 100644 --- a/src/target.c +++ b/src/target.c @@ -22,6 +22,8 @@ #include "target.h" #include "target_internal.h" +#include + target *target_list = NULL; target *target_new(void) @@ -48,8 +50,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); + if (target_list->tc) + target_list->tc->destroy_callback(target_list->tc, target_list); if (target_list->priv) target_list->priv_free(target_list->priv); while (target_list->commands) { @@ -90,22 +92,22 @@ void target_add_commands(target *t, const struct command_s *cmds, const char *na tc->next = NULL; } -target *target_attach_n(int n, target_destroy_callback destroy_cb) +target *target_attach_n(int n, struct target_controller *tc) { target *t; int i; for(t = target_list, i = 1; t; t = t->next, i++) if(i == n) - return target_attach(t, destroy_cb); + return target_attach(t, tc); return NULL; } -target *target_attach(target *t, target_destroy_callback destroy_cb) +target *target_attach(target *t, struct target_controller *tc) { - if (t->destroy_callback) - t->destroy_callback(t); + if (t->tc) + t->tc->destroy_callback(t->tc, t); - t->destroy_callback = destroy_cb; + t->tc = tc; if (!t->attach(t)) return NULL; @@ -418,13 +420,12 @@ int target_command(target *t, int argc, const char *argv[]) return -1; } -#include "gdb_packet.h" void tc_printf(target *t, const char *fmt, ...) { (void)t; va_list ap; va_start(ap, fmt); - gdb_voutf(fmt, ap); + t->tc->printf(t->tc, fmt, ap); va_end(ap); } diff --git a/src/target_internal.h b/src/target_internal.h index ea0bfbc5..e8f6cc1c 100644 --- a/src/target_internal.h +++ b/src/target_internal.h @@ -70,8 +70,7 @@ struct target_command_s { struct target_s { bool attached; - /* Notify controlling debugger if target is lost */ - target_destroy_callback destroy_callback; + struct target_controller *tc; /* Attach/Detach funcitons */ bool (*attach)(target *t);