* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
- * Copyright (C) 2007-2009 Øyvind Harboe *
+ * Copyright (C) 2007-2010 Øyvind Harboe *
* oyvind.harboe@zylin.com *
* *
* Copyright (C) 2008 by Spencer Oliver *
bool sync; /* set flag to true if you want the next stepi to return immediately.
allowing GDB to pick up a fresh set of register values from the target
without modifying the target state. */
-
+ /* We delay reporting memory write errors until next step/continue or memory
+ * write. This improves performance of gdb load significantly as the GDB packet
+ * can be replied immediately and a new GDB packet will be ready without delay
+ * (ca. 10% or so...).
+ */
+ bool mem_write_error;
};
struct gdb_connection *gdb_con = connection->priv;
int retval = ERROR_OK;
+#ifdef _DEBUG_GDB_IO_
+ char *debug_buffer;
+#endif
for (;;)
{
if (connection->service->type == CONNECTION_PIPE)
gdb_connection->busy = 0;
gdb_connection->noack_mode = 0;
gdb_connection->sync = true;
+ gdb_connection->mem_write_error = false;
/* send ACK to GDB for debug request */
gdb_write(connection, "+", 1);
gdb_putback_char(connection, initial_ack);
target_call_event_callbacks(gdb_service->target, TARGET_EVENT_GDB_ATTACH);
+ if (gdb_use_memory_map)
+ {
+ /* Connect must fail if the memory map can't be set up correctly.
+ *
+ * This will cause an auto_probe to be invoked, which is either
+ * a no-op or it will fail when the target isn't ready(e.g. not halted).
+ */
+ int i;
+ for (i = 0; i < flash_get_bank_count(); i++)
+ {
+ struct flash_bank *p;
+ retval = get_flash_bank_by_num(i, &p);
+ if (retval != ERROR_OK)
+ {
+ LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect.");
+ return retval;
+ }
+ }
+ }
+
gdb_actual_connections++;
LOG_DEBUG("New GDB Connection: %d, Target %s, state: %s",
gdb_actual_connections,
uint32_t addr = 0;
uint32_t len = 0;
- int retval;
+ int retval = ERROR_OK;
/* skip command character */
packet++;
return ERROR_SERVER_REMOTE_CLOSED;
}
- retval = ERROR_OK;
- if (len)
- {
- LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
+ struct gdb_connection *gdb_connection = connection->priv;
- retval = target_write_buffer(target, addr, len, (uint8_t*)separator);
+ if (gdb_connection->mem_write_error)
+ {
+ retval = ERROR_FAIL;
+ /* now that we have reported the memory write error, we can clear the condition */
+ gdb_connection->mem_write_error = false;
}
+ /* By replying the packet *immediately* GDB will send us a new packet
+ * while we write the last one to the target.
+ */
if (retval == ERROR_OK)
{
gdb_put_packet(connection, "OK", 2);
return retval;
}
+ if (len)
+ {
+ LOG_DEBUG("addr: 0x%8.8" PRIx32 ", len: 0x%8.8" PRIx32 "", addr, len);
+
+ retval = target_write_buffer(target, addr, len, (uint8_t*)separator);
+ if (retval != ERROR_OK)
+ {
+ gdb_connection->mem_write_error = true;
+ }
+ }
+
return ERROR_OK;
}
banks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count());
for (i = 0; i < flash_get_bank_count(); i++) {
- p = get_flash_bank_by_num(i);
- if (p == NULL) {
+ retval = get_flash_bank_by_num(i, &p);
+ if (retval != ERROR_OK)
+ {
free(banks);
- retval = ERROR_FAIL;
gdb_send_error(connection, retval);
return retval;
}
struct gdb_connection *gdb_con = connection->priv;
log_add_callback(gdb_log_callback, connection);
+ if (gdb_con->mem_write_error)
+ {
+ LOG_ERROR("Memory write failure!");
+
+ /* now that we have reported the memory write error, we can clear the condition */
+ gdb_con->mem_write_error = false;
+ }
+
bool nostep = false;
bool already_running = false;
if (target->state == TARGET_RUNNING)
COMMAND_HANDLER(handle_gdb_memory_map_command)
{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_use_memory_map);
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- return ERROR_COMMAND_SYNTAX_ERROR;
+ COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_use_memory_map);
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_gdb_flash_program_command)
{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_flash_program);
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- return ERROR_COMMAND_SYNTAX_ERROR;
+ COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_flash_program);
+ return ERROR_OK;
}
COMMAND_HANDLER(handle_gdb_report_data_abort_command)
{
- if (CMD_ARGC == 1)
- COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_report_data_abort);
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- return ERROR_COMMAND_SYNTAX_ERROR;
+ COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_report_data_abort);
+ return ERROR_OK;
}
/* gdb_breakpoint_override */