- added patch to Improving progress/error output for telnet & GDB monitor
[openocd.git] / src / server / gdb_server.c
index d094a0c96f4f0078485b9b5d2d4677b46e33c79b..b15c29d38be3397c8f6df091d6c755f2019ce21d 100644 (file)
 
 static unsigned short gdb_port;
 
+static void gdb_log_callback(void *privData, const char *file, int line, 
+               const char *function, const char *format, va_list args);
+
+
 enum gdb_detach_mode
 {
        GDB_DETACH_RESUME,
@@ -180,7 +184,7 @@ int gdb_putback_char(connection_t *connection, int last_char)
        return ERROR_OK;
 }
 
-int gdb_put_packet(connection_t *connection, char *buffer, int len)
+int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
 {
        int i;
        unsigned char my_checksum = 0;
@@ -245,10 +249,19 @@ int gdb_put_packet(connection_t *connection, char *buffer, int len)
        return ERROR_OK;
 }
 
-int gdb_get_packet(connection_t *connection, char *buffer, int *len)
+int gdb_put_packet(connection_t *connection, char *buffer, int len)
+{
+       gdb_connection_t *gdb_connection = connection->priv;
+       gdb_connection->output_disable=1;
+       int retval=gdb_put_packet_inner(connection, buffer, len);
+       gdb_connection->output_disable=0;
+       return retval;
+}
+
+int gdb_get_packet_inner(connection_t *connection, char *buffer, int *len)
 {
        int character;
-       int count;
+       int count = 0;
        int retval;
        char checksum[3];
        unsigned char my_checksum = 0;
@@ -286,8 +299,9 @@ int gdb_get_packet(connection_t *connection, char *buffer, int *len)
                } while (character != '$');
 
                my_checksum = 0;
-               count = 0;
                
+               count=0;
+               gdb_connection_t *gdb_con = connection->priv;
                for (;;)
                {
                        /* The common case is that we have an entire packet with no escape chars.
@@ -391,11 +405,18 @@ int gdb_get_packet(connection_t *connection, char *buffer, int *len)
        return ERROR_OK;
 }
 
-int gdb_output(struct command_context_s *context, char* line)
+int gdb_get_packet(connection_t *connection, char *buffer, int *len)
 {
-       connection_t *connection = context->output_handler_priv;
        gdb_connection_t *gdb_connection = connection->priv;
+       gdb_connection->output_disable=1;
+       int retval=gdb_get_packet_inner(connection, buffer, len);
+       gdb_connection->output_disable=0;
+       return retval;
+}
        
+int gdb_output_con(connection_t *connection, char* line)
+{
+       gdb_connection_t *gdb_connection = connection->priv;
        char *hex_buffer;
        int i, bin_size;
 
@@ -422,6 +443,12 @@ int gdb_output(struct command_context_s *context, char* line)
        return ERROR_OK;
 }
 
+int gdb_output(struct command_context_s *context, char* line)
+{
+       connection_t *connection = context->output_handler_priv;
+       return gdb_output_con(connection, line);
+}
+
 int gdb_program_handler(struct target_s *target, enum target_event event, void *priv)
 {
        FILE *script;
@@ -458,6 +485,9 @@ int gdb_target_callback_event_handler(struct target_s *target, enum target_event
                case TARGET_EVENT_HALTED:
                        if (gdb_connection->frontend_state == TARGET_RUNNING)
                        {
+                               // stop forwarding log packets!
+                               log_setCallback(NULL, NULL);
+                               
                                if (gdb_connection->ctrl_c)
                                {
                                        signal = 0x2;
@@ -895,7 +925,6 @@ int gdb_memory_packet_error(connection_t *connection, int retval)
                case ERROR_TARGET_NOT_HALTED:
                        ERROR("gdb tried to read memory but we're not halted, dropping connection");
                        return ERROR_SERVER_REMOTE_CLOSED;
-                       break;
                case ERROR_TARGET_DATA_ABORT:
                        gdb_send_error(connection, EIO);
                        break;
@@ -1364,6 +1393,22 @@ static int decode_xfer_read (char *buf, char **annex, int *ofs, unsigned int *le
        return 0;
 }
 
+int gdb_calc_blocksize(flash_bank_t *bank)
+{
+       int i;
+       int block_size = 0xffffffff;
+       
+       /* loop through all sectors and return smallest sector size */
+       
+       for (i = 0; i < bank->num_sectors; i++)
+       {
+               if (bank->sectors[i].size < block_size)
+                       block_size = bank->sectors[i].size;
+       }
+       
+       return block_size;
+}
+
 int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
 {
        command_context_t *cmd_ctx = connection->cmd_ctx;
@@ -1382,6 +1427,9 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
                                cmd[i] = tmp;
                        }
                        cmd[(packet_size - 6)/2] = 0x0;
+                       
+                       /* We want to print all debug output to GDB connection */
+                       log_setCallback(gdb_log_callback, connection);
                        target_call_timer_callbacks();
                        command_run_line(cmd_ctx, cmd);
                        free(cmd);
@@ -1470,6 +1518,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
                int offset;
                int length;
                char *separator;
+               int blocksize;
                
                /* skip command character */
                packet += 23;
@@ -1486,10 +1535,14 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
                        if (p == NULL)
                                break;
                        
+                       /* if device has uneven sector sizes, eg. str7, lpc
+                        * we pass the smallest sector size to gdb memory map */
+                       blocksize = gdb_calc_blocksize(p);
+                       
                        xml_printf(&retval, &xml, &pos, &size, "<memory type=\"flash\" start=\"0x%x\" length=\"0x%x\">\n" \
                                "<property name=\"blocksize\">0x%x</property>\n" \
                                "</memory>\n", \
-                               p->base, p->size, p->size/p->num_sectors);
+                               p->base, p->size, blocksize);
                        i++;
                }
                
@@ -1738,6 +1791,22 @@ int gdb_detach(connection_t *connection, target_t *target)
        return ERROR_OK;
 }
 
+
+
+static void gdb_log_callback(void *privData, const char *file, int line, 
+               const char *function, const char *format, va_list args)
+{
+       connection_t *connection=(connection_t *)privData;
+       
+       char *t=allocPrintf(format, args);
+       if (t==NULL)
+               return;
+       
+       gdb_output_con(connection, t); 
+       
+       free(t);
+}
+
 int gdb_input(connection_t *connection)
 {
        gdb_service_t *gdb_service = connection->service->priv;
@@ -1812,6 +1881,9 @@ int gdb_input(connection_t *connection)
                                        break;
                                case 'c':
                                case 's':
+                                       /* We're running/stepping, in which case we can 
+                                        * forward log output until the target is halted */
+                                       log_setCallback(gdb_log_callback, connection);
                                        gdb_step_continue_packet(connection, target, packet, packet_size);
                                        break;
                                case 'v':

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)