remove flash.h from tree
[openocd.git] / src / server / gdb_server.c
index 9581ea63aa35e45abba3ca245c52850971374ccd..f9cca99f37e0ad24a8d4e37c261427ad77636f09 100644 (file)
 #include "config.h"
 #endif
 
-#include "breakpoints.h"
-#include "target_request.h"
-#include "register.h"
+#include <target/breakpoints.h>
+#include <target/target_request.h>
+#include <target/register.h>
 #include "server.h"
-#include "flash.h"
+#include <flash/nor/core.h>
 #include "gdb_server.h"
-#include "image.h"
-#include "jtag.h"
+#include <target/image.h>
+#include <jtag/jtag.h>
 
 
 #if 0
@@ -48,12 +48,13 @@ static enum breakpoint_type gdb_breakpoint_override_type;
 
 extern int gdb_error(struct connection *connection, int retval);
 static unsigned short gdb_port = 3333;
+static unsigned short gdb_port_next = 0;
 static const char *DIGITS = "0123456789abcdef";
 
 static void gdb_log_callback(void *priv, const char *file, unsigned line,
                const char *function, const char *string);
 
-/* number of gdb connections, mainly to supress gdb related debugging spam
+/* number of gdb connections, mainly to suppress gdb related debugging spam
  * in helper/log.c when no gdb connections are actually active */
 int gdb_actual_connections;
 
@@ -568,7 +569,7 @@ int gdb_get_packet_inner(struct connection *connection, char *buffer, int *len)
                                        break;
                                case '+':
                                        /* gdb sends a dummy ack '+' at every remote connect - see remote_start_remote (remote.c)
-                                        * incase anyone tries to debug why they receive this warning every time */
+                                        * in case anyone tries to debug why they receive this warning every time */
                                        LOG_WARNING("acknowledgment received, but no packet pending");
                                        break;
                                case '-':
@@ -774,7 +775,7 @@ int gdb_new_connection(struct connection *connection)
        gdb_actual_connections++;
        LOG_DEBUG("New GDB Connection: %d, Target %s, state: %s",
                  gdb_actual_connections,
-                 gdb_service->target->cmd_name,
+                 target_name(gdb_service->target),
                  target_state_name(gdb_service->target));
 
        return ERROR_OK;
@@ -792,7 +793,7 @@ int gdb_connection_closed(struct connection *connection)
 
        gdb_actual_connections--;
        LOG_DEBUG("GDB Close, Target: %s, state: %s, gdb_actual_connections=%d",
-                 gdb_service->target->cmd_name,
+                 target_name(gdb_service->target),
                  target_state_name(gdb_service->target),
                  gdb_actual_connections);
 
@@ -859,7 +860,7 @@ static int gdb_reg_pos(struct target *target, int pos, int len)
  * register might be non-divisible by 8(a byte), in which
  * case an entire byte is shown.
  *
- * NB! the format on the wire is the target endianess
+ * NB! the format on the wire is the target endianness
  *
  * The format of reg->value is little endian
  *
@@ -2138,10 +2139,10 @@ int gdb_input_inner(struct connection *connection)
                                        watchpoint_clear_target(gdb_service->target);
                                        command_run_linef(connection->cmd_ctx,
                                                        "ocd_gdb_restart %s",
-                                                       target->cmd_name);
+                                                       target_name(target));
                                        break;
                                default:
-                                       /* ignore unkown packets */
+                                       /* ignore unknown packets */
                                        LOG_DEBUG("ignoring 0x%2.2x packet", packet[0]);
                                        gdb_put_packet(connection, NULL, 0);
                                        break;
@@ -2189,55 +2190,72 @@ int gdb_input(struct connection *connection)
        return ERROR_OK;
 }
 
-int gdb_init(void)
+static int gdb_target_start(struct target *target, uint16_t port)
 {
-       struct gdb_service *gdb_service;
-       struct target *target = all_targets;
+       bool use_pipes = 0 == port;
+       struct gdb_service *gdb_service = malloc(sizeof(struct gdb_service));
+       if (NULL == gdb_service)
+               return -ENOMEM;
 
-       if (!target)
-       {
-               LOG_WARNING("no gdb ports allocated as no target has been specified");
-               return ERROR_OK;
-       }
+       gdb_service->target = target;
+
+       add_service("gdb", use_pipes ? CONNECTION_PIPE : CONNECTION_TCP,
+                       port, 1, &gdb_new_connection, &gdb_input,
+                       &gdb_connection_closed, gdb_service);
 
+       const char *name = target_name(target);
+       if (use_pipes)
+               LOG_DEBUG("gdb service for target '%s' using pipes", name);
+       else
+               LOG_DEBUG("gdb service for target '%s' on TCP port %u", name, port);
+       return ERROR_OK;
+}
+
+int gdb_target_add_one(struct target *target)
+{
        if (gdb_port == 0 && server_use_pipes == 0)
        {
                LOG_INFO("gdb port disabled");
                return ERROR_OK;
        }
+       if (0 == gdb_port_next)
+               gdb_port_next = gdb_port;
 
-       if (server_use_pipes)
+       bool use_pipes = server_use_pipes;
+       static bool server_started_with_pipes = false;
+       if (server_started_with_pipes)
        {
-               /* only a single gdb connection when using a pipe */
+               LOG_WARNING("gdb service permits one target when using pipes");
+               if (0 == gdb_port)
+                       return ERROR_OK;
 
-               gdb_service = malloc(sizeof(struct gdb_service));
-               gdb_service->target = target;
+               use_pipes = false;
+       }
 
-               add_service("gdb", CONNECTION_PIPE, 0, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
+       int e = gdb_target_start(target, use_pipes ? 0 : gdb_port_next);
+       if (ERROR_OK == e)
+       {
+               server_started_with_pipes |= use_pipes;
+               gdb_port_next++;
+       }
+       return e;
+}
 
-               LOG_DEBUG("gdb service for target %s using pipes",
-                               target_get_name(target));
+int gdb_target_add_all(struct target *target)
+{
+       if (NULL == target)
+       {
+               LOG_WARNING("gdb services need one or more targets defined");
+               return ERROR_OK;
        }
-       else
+
+       while (NULL != target)
        {
-               unsigned short port = gdb_port;
+               int retval = gdb_target_add_one(target);
+               if (ERROR_OK != retval)
+                       return retval;
 
-               while (target)
-               {
-                       gdb_service = malloc(sizeof(struct gdb_service));
-                       gdb_service->target = target;
-
-                       add_service("gdb", CONNECTION_TCP,
-                                       port, 1,
-                                       gdb_new_connection, gdb_input,
-                                       gdb_connection_closed, gdb_service);
-
-                       LOG_DEBUG("gdb service for target %s at TCP port %i",
-                                       target_get_name(target),
-                                       port);
-                       target = target->next;
-                       port++;
-               }
+               target = target->next;
        }
 
        return ERROR_OK;
@@ -2245,14 +2263,14 @@ int gdb_init(void)
 
 COMMAND_HANDLER(handle_gdb_sync_command)
 {
-       if (argc != 0)
+       if (CMD_ARGC != 0)
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        if (current_gdb_connection == NULL)
        {
-               command_print(cmd_ctx,
+               command_print(CMD_CTX,
                                "gdb_sync command can only be run from within gdb using \"monitor gdb_sync\"");
                return ERROR_FAIL;
        }
@@ -2265,68 +2283,32 @@ COMMAND_HANDLER(handle_gdb_sync_command)
 /* daemon configuration command gdb_port */
 COMMAND_HANDLER(handle_gdb_port_command)
 {
-       return CALL_COMMAND_HANDLER(server_port_command, &gdb_port);
+       int retval = CALL_COMMAND_HANDLER(server_port_command, &gdb_port);
+       if (ERROR_OK == retval)
+               gdb_port_next = gdb_port;
+       return retval;
 }
 
 COMMAND_HANDLER(handle_gdb_memory_map_command)
 {
-       if (argc == 1)
-       {
-               if (strcmp(args[0], "enable") == 0)
-               {
-                       gdb_use_memory_map = 1;
-                       return ERROR_OK;
-               }
-               else if (strcmp(args[0], "disable") == 0)
-               {
-                       gdb_use_memory_map = 0;
-                       return ERROR_OK;
-               }
-               else
-                       LOG_WARNING("invalid gdb_memory_map configuration directive %s", args[0]);
-       }
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_use_memory_map);
 
        return ERROR_COMMAND_SYNTAX_ERROR;
 }
 
 COMMAND_HANDLER(handle_gdb_flash_program_command)
 {
-       if (argc == 1)
-       {
-               if (strcmp(args[0], "enable") == 0)
-               {
-                       gdb_flash_program = 1;
-                       return ERROR_OK;
-               }
-               else if (strcmp(args[0], "disable") == 0)
-               {
-                       gdb_flash_program = 0;
-                       return ERROR_OK;
-               }
-               else
-                       LOG_WARNING("invalid gdb_flash_program configuration directive: %s", args[0]);
-       }
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_flash_program);
 
        return ERROR_COMMAND_SYNTAX_ERROR;
 }
 
 COMMAND_HANDLER(handle_gdb_report_data_abort_command)
 {
-       if (argc == 1)
-       {
-               if (strcmp(args[0], "enable") == 0)
-               {
-                       gdb_report_data_abort = 1;
-                       return ERROR_OK;
-               }
-               else if (strcmp(args[0], "disable") == 0)
-               {
-                       gdb_report_data_abort = 0;
-                       return ERROR_OK;
-               }
-               else
-                       LOG_WARNING("invalid gdb_report_data_abort configuration directive: %s", args[0]);
-       }
+       if (CMD_ARGC == 1)
+               COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_report_data_abort);
 
        return ERROR_COMMAND_SYNTAX_ERROR;
 }
@@ -2334,19 +2316,19 @@ COMMAND_HANDLER(handle_gdb_report_data_abort_command)
 /* gdb_breakpoint_override */
 COMMAND_HANDLER(handle_gdb_breakpoint_override_command)
 {
-       if (argc == 0)
+       if (CMD_ARGC == 0)
        {
 
-       } else if (argc == 1)
+       } else if (CMD_ARGC == 1)
        {
                gdb_breakpoint_override = 1;
-               if (strcmp(args[0], "hard") == 0)
+               if (strcmp(CMD_ARGV[0], "hard") == 0)
                {
                        gdb_breakpoint_override_type = BKPT_HARD;
-               } else if (strcmp(args[0], "soft") == 0)
+               } else if (strcmp(CMD_ARGV[0], "soft") == 0)
                {
                        gdb_breakpoint_override_type = BKPT_SOFT;
-               } else if (strcmp(args[0], "disable") == 0)
+               } else if (strcmp(CMD_ARGV[0], "disable") == 0)
                {
                        gdb_breakpoint_override = 0;
                }
@@ -2359,33 +2341,61 @@ COMMAND_HANDLER(handle_gdb_breakpoint_override_command)
                LOG_USER("force %s breakpoints", (gdb_breakpoint_override_type == BKPT_HARD)?"hard":"soft");
        } else
        {
-               LOG_USER("breakpoint type is not overriden");
+               LOG_USER("breakpoint type is not overridden");
        }
 
        return ERROR_OK;
 }
 
-int gdb_register_commands(struct command_context *command_context)
+static const struct command_registration gdb_command_handlers[] = {
+       {
+               .name = "gdb_sync",
+               .handler = &handle_gdb_sync_command,
+               .mode = COMMAND_ANY,
+               .help = "next stepi will return immediately allowing "
+                       "GDB to fetch register state without affecting "
+                       "target state",
+       },
+       {
+               .name = "gdb_port",
+               .handler = &handle_gdb_port_command,
+               .mode = COMMAND_ANY,
+               .help = "daemon configuration command gdb_port",
+               .usage = "<port>",
+       },
+       {
+               .name = "gdb_memory_map",
+               .handler = &handle_gdb_memory_map_command,
+               .mode = COMMAND_CONFIG,
+               .help = "enable or disable memory map",
+               .usage = "enable|disable"
+       },
+       {
+               .name = "gdb_flash_program",
+               .handler = &handle_gdb_flash_program_command,
+               .mode = COMMAND_CONFIG,
+               .help = "enable or disable flash program",
+               .usage = "enable|disable"
+       },
+       {
+               .name = "gdb_report_data_abort",
+               .handler = &handle_gdb_report_data_abort_command,
+               .mode = COMMAND_CONFIG,
+               .help = "enable or disable reporting data aborts",
+               .usage = "enable|disable"
+       },
+       {
+               .name = "gdb_breakpoint_override",
+               .handler = &handle_gdb_breakpoint_override_command,
+               .mode = COMMAND_EXEC,
+               .help = "force type of breakpoint "
+                       "used by gdb 'break' commands.",
+               .usage = "hard|soft|disable",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+int gdb_register_commands(struct command_context *cmd_ctx)
 {
-       register_command(command_context, NULL, "gdb_sync",
-                       handle_gdb_sync_command, COMMAND_ANY,
-                       "next stepi will return immediately allowing GDB to "
-                       "fetch register state without affecting target state");
-       register_command(command_context, NULL, "gdb_port",
-                       handle_gdb_port_command, COMMAND_ANY,
-                       "daemon configuration command gdb_port");
-       register_command(command_context, NULL, "gdb_memory_map",
-                       handle_gdb_memory_map_command, COMMAND_CONFIG,
-                       "enable or disable memory map");
-       register_command(command_context, NULL, "gdb_flash_program",
-                       handle_gdb_flash_program_command, COMMAND_CONFIG,
-                       "enable or disable flash program");
-       register_command(command_context, NULL, "gdb_report_data_abort",
-                       handle_gdb_report_data_abort_command, COMMAND_CONFIG,
-                       "enable or disable reporting data aborts");
-       register_command(command_context, NULL, "gdb_breakpoint_override",
-                       handle_gdb_breakpoint_override_command, COMMAND_EXEC,
-                       "hard/soft/disable - force type of breakpoint "
-                       "used by gdb 'break' commands.");
-       return ERROR_OK;
+       return register_commands(cmd_ctx, NULL, gdb_command_handlers);
 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)