duan ellis target tcl work in progress
[openocd.git] / src / server / gdb_server.c
index 3f346584efa724125b1a3e4ed3e2d321220101ed..8fb3b64f954f1c539516f14cc7024e6585f6600e 100644 (file)
@@ -2,7 +2,7 @@
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
  *                                                                         *
- *   Copyright (C) 2007,2008 Øyvind Harboe                                      *
+ *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -46,6 +46,9 @@
 #define _DEBUG_GDB_IO_
 #endif
 
+static int gdb_breakpoint_override;
+static enum breakpoint_type gdb_breakpoint_override_type;
+
 extern int gdb_error(connection_t *connection, int retval);
 static unsigned short gdb_port;
 static const char *DIGITS = "0123456789abcdef";
@@ -335,7 +338,10 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
                        gdb_write(connection, buffer, len);
                        gdb_write(connection, local_buffer+1, 3);
                }
-
+               
+               if (gdb_con->noack_mode)
+                       break;
+               
                if ((retval = gdb_get_char(connection, &reply)) != ERROR_OK)
                        return retval;
 
@@ -474,7 +480,8 @@ int gdb_get_packet_inner(connection_t *connection, char *buffer, int *len)
                                                i++;
                                                my_checksum += character & 0xff;
                                                buffer[count++] = (character ^ 0x20) & 0xff;
-                                       } else
+                                       }
+                                       else
                                        {
                                                my_checksum += character & 0xff;
                                                buffer[count++] = character & 0xff;
@@ -512,7 +519,6 @@ int gdb_get_packet_inner(connection_t *connection, char *buffer, int *len)
                                my_checksum += character & 0xff;
                                buffer[count++] = character & 0xff;
                        }
-
                }
 
                *len = count;
@@ -527,12 +533,22 @@ int gdb_get_packet_inner(connection_t *connection, char *buffer, int *len)
 
                if (my_checksum == strtoul(checksum, NULL, 16))
                {
+                       if (gdb_con->noack_mode)
+                               break;
                        gdb_write(connection, "+", 1);
                        break;
                }
 
-               LOG_WARNING("checksum error, requesting retransmission");
-               gdb_write(connection, "-", 1);
+               if (!gdb_con->noack_mode)
+               {
+                       LOG_WARNING("checksum error, requesting retransmission");
+                       gdb_write(connection, "-", 1);
+               }
+               else
+               {
+                       LOG_WARNING("checksum error, no-ack-mode");
+                       break;
+               }
        }
        if (gdb_con->closed)
                return ERROR_SERVER_REMOTE_CLOSED;
@@ -633,7 +649,7 @@ int gdb_target_callback_event_handler(struct target_s *target, enum target_event
                case TARGET_EVENT_HALTED:
                        gdb_frontend_halted(target, connection);
                        break;
-               case TARGET_EVENT_GDB_PROGRAM:
+               case TARGET_EVENT_GDB_FLASH_ERASE_START:
                        gdb_program_handler(target, event, connection->cmd_ctx);
                        break;
                default:
@@ -661,6 +677,7 @@ int gdb_new_connection(connection_t *connection)
        gdb_connection->vflash_image = NULL;
        gdb_connection->closed = 0;
        gdb_connection->busy = 0;
+       gdb_connection->noack_mode = 0;
        
        /* send ACK to GDB for debug request */
        gdb_write(connection, "+", 1);
@@ -1277,6 +1294,11 @@ int gdb_breakpoint_watchpoint_packet(connection_t *connection, target_t *target,
                wp_type = WPT_READ;
        else if (type == 4) /* access watchpoint */
                wp_type = WPT_ACCESS;
+       
+       if (gdb_breakpoint_override&&((bp_type==BKPT_SOFT)||(bp_type==BKPT_HARD)))
+       {
+               bp_type=gdb_breakpoint_override_type;
+       }
 
        if (*separator != ',')
        {
@@ -1451,7 +1473,8 @@ static int compare_bank (const void * a, const void * b)
 int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
 {
        command_context_t *cmd_ctx = connection->cmd_ctx;
-
+       gdb_connection_t *gdb_connection = connection->priv;
+       
        if (strstr(packet, "qRcmd,"))
        {
                if (packet_size > 6)
@@ -1528,7 +1551,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
                int size = 0;
 
                xml_printf(&retval, &buffer, &pos, &size,
-                               "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-",
+                               "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-;QStartNoAckMode+",
                                (GDB_BUFFER_SIZE - 1), ((gdb_use_memory_map == 1)&&(flash_get_bank_count()>0)) ? '+' : '-');
 
                if (retval != ERROR_OK)
@@ -1688,6 +1711,12 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
                free(xml);
                return ERROR_OK;
        }
+       else if (strstr(packet, "QStartNoAckMode"))
+       {
+               gdb_connection->noack_mode = 1;
+               gdb_put_packet(connection, "OK", 2);
+               return ERROR_OK;
+       }
 
        gdb_put_packet(connection, "", 0);
        return ERROR_OK;
@@ -1740,7 +1769,7 @@ int gdb_v_packet(connection_t *connection, target_t *target, char *packet, int p
                flash_set_dirty();
 
                /* perform any target specific operations before the erase */
-               target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_PROGRAM);
+               target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_FLASH_ERASE_START);
 
                /* perform erase */
                if ((result = flash_erase_address_range(gdb_service->target, addr, length)) != ERROR_OK)
@@ -1909,6 +1938,7 @@ int gdb_input_inner(connection_t *connection)
                                        gdb_put_packet(connection, NULL, 0);
                                        break;
                                case 'q':
+                               case 'Q':
                                        retval = gdb_query_packet(connection, target, packet, packet_size);
                                        break;
                                case 'g':
@@ -1985,6 +2015,8 @@ int gdb_input_inner(connection_t *connection)
                                        break;
                                case 'R':
                                        /* handle extended restart packet */
+                                       breakpoint_clear_target(gdb_service->target);
+                                       watchpoint_clear_target(gdb_service->target);
                                        command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %d", get_num_by_target(target));
                                        break;
                                default:
@@ -2031,8 +2063,7 @@ int gdb_input(connection_t *connection)
 int gdb_init(void)
 {
        gdb_service_t *gdb_service;
-       target_t *target = targets;
-       int i = 0;
+       target_t *target = all_targets;
 
        if (!target)
        {
@@ -2050,16 +2081,21 @@ int gdb_init(void)
        {
                char service_name[8];
 
-               snprintf(service_name, 8, "gdb-%2.2i", i);
+               snprintf(service_name, 8, "gdb-%2.2i", target->target_number);
 
                gdb_service = malloc(sizeof(gdb_service_t));
                gdb_service->target = target;
 
-               add_service("gdb", CONNECTION_GDB, gdb_port + i, 1, gdb_new_connection, gdb_input, gdb_connection_closed, gdb_service);
+               add_service("gdb", CONNECTION_GDB, 
+                           gdb_port + target->target_number, 
+                           1, gdb_new_connection, gdb_input, 
+                           gdb_connection_closed, 
+                           gdb_service);
 
-               LOG_DEBUG("gdb service for target %s at port %i", target->type->name, gdb_port + i);
+               LOG_DEBUG("gdb service for target %s at port %i", 
+                         target->type->name, 
+                         gdb_port + target->target_number);
 
-               i++;
                target = target->next;
        }
 
@@ -2169,6 +2205,41 @@ int handle_gdb_report_data_abort_command(struct command_context_s *cmd_ctx, char
        return ERROR_OK;
 }
 
+/* daemon configuration command gdb_port */
+int handle_gdb_breakpoint_override_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc == 0)
+       {
+               
+       } else if (argc==1)
+       {
+               gdb_breakpoint_override = 1;
+               if (strcmp(args[0], "hard")==0)
+               {
+                       gdb_breakpoint_override_type=BKPT_HARD;
+               } else if (strcmp(args[0], "soft")==0)
+               {
+                       gdb_breakpoint_override_type=BKPT_SOFT;
+               } else if (strcmp(args[0], "disable") == 0)
+               {
+                       gdb_breakpoint_override = 0;
+               }
+       } else
+       {
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+       if (gdb_breakpoint_override)
+       {
+               LOG_USER("force %s breakpoints", (gdb_breakpoint_override_type==BKPT_HARD)?"hard":"soft");
+       } else
+       {
+               LOG_USER("breakpoint type is not overriden");
+       }
+       
+       return ERROR_OK;
+}
+
+
 int gdb_register_commands(command_context_t *command_context)
 {
        register_command(command_context, NULL, "gdb_port", handle_gdb_port_command,
@@ -2181,5 +2252,10 @@ int gdb_register_commands(command_context_t *command_context)
                        COMMAND_CONFIG, "");
        register_command(command_context, NULL, "gdb_report_data_abort", handle_gdb_report_data_abort_command,
                        COMMAND_CONFIG, "");
+       register_command(command_context, NULL, "gdb_breakpoint_override", handle_gdb_breakpoint_override_command,
+                       COMMAND_EXEC, "hard/soft/disabled - force breakpoint type for gdb 'break' commands."
+                       "The raison d'etre for this option is to support GDB GUI's without "
+                       "a hard/soft breakpoint concept where the default OpenOCD behaviour "
+                       "is not sufficient");
        return ERROR_OK;
 }

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)