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,
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;
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;
} 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.
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;
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;
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;
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;
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;
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);
int offset;
int length;
char *separator;
+ int blocksize;
/* skip command character */
packet += 23;
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++;
}
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;
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':