X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fserver%2Fgdb_server.c;h=17ca4398e6b3977f5b57061895d994a7cb789f4c;hb=c6e323b9838254b338310ec165a5345635c5d177;hp=6ed7243d28498f1889caca7c4d72936b4628367c;hpb=44aaba3d08bebbd809aabbe1c05d5aecb54eff12;p=openocd
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 6ed7243d..17ca4398 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1613,22 +1613,6 @@ static int decode_xfer_read(char *buf, char **annex, int *ofs, unsigned int *len
return 0;
}
-static int gdb_calc_blocksize(struct flash_bank *bank)
-{
- uint32_t i;
- uint32_t block_size = 0xffffffff;
-
- /* loop through all sectors and return smallest sector size */
-
- for (i = 0; i < (uint32_t)bank->num_sectors; i++)
- {
- if (bank->sectors[i].size < block_size)
- block_size = bank->sectors[i].size;
- }
-
- return block_size;
-}
-
static int compare_bank (const void * a, const void * b)
{
struct flash_bank *b1, *b2;
@@ -1666,7 +1650,6 @@ static int gdb_memory_map(struct connection *connection,
int offset;
int length;
char *separator;
- int blocksize;
uint32_t ram_start = 0;
int i;
@@ -1683,6 +1666,7 @@ static int gdb_memory_map(struct connection *connection,
* it has no concept of non-cacheable read/write memory (i/o etc).
*
* FIXME Most non-flash addresses are *NOT* RAM! Don't lie.
+ * Current versions of GDB assume unlisted addresses are RAM...
*/
banks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count());
@@ -1701,29 +1685,60 @@ static int gdb_memory_map(struct connection *connection,
compare_bank);
for (i = 0; i < flash_get_bank_count(); i++) {
+ int j;
+ unsigned sector_size = 0;
+ uint32_t start, end;
+
p = banks[i];
+ start = p->base;
+ end = p->base + p->size;
if (ram_start < p->base)
xml_printf(&retval, &xml, &pos, &size,
"\n",
- ram_start, p->base-ram_start);
+ ram_start, p->base - ram_start);
- /* If device has uneven sector sizes, eg. str7, lpc
- * we pass the smallest sector size to gdb memory map
- *
- * FIXME Don't lie about flash regions with different
- * sector sizes; just tell GDB about each region as
- * if it were a separate flash device.
+ /* Report adjacent groups of same-size sectors. So for
+ * example top boot CFI flash will list an initial region
+ * with several large sectors (maybe 128KB) and several
+ * smaller ones at the end (maybe 32KB). STR7 will have
+ * regions with 8KB, 32KB, and 64KB sectors; etc.
*/
- blocksize = gdb_calc_blocksize(p);
+ for (j = 0; j < p->num_sectors; j++) {
+ unsigned group_len;
+
+ /* Maybe start a new group of sectors. */
+ if (sector_size == 0) {
+ start = p->base + p->sectors[j].offset;
+ xml_printf(&retval, &xml, &pos, &size,
+ "sectors[j].size;
+ }
+
+ /* Does this finish a group of sectors?
+ * If not, continue an already-started group.
+ */
+ if (j == p->num_sectors -1)
+ group_len = (p->base + p->size) - start;
+ else if (p->sectors[j + 1].size != sector_size)
+ group_len = p->base + p->sectors[j + 1].offset
+ - start;
+ else
+ continue;
+
+ xml_printf(&retval, &xml, &pos, &size,
+ "length=\"0x%x\">\n"
+ ""
+ "0x%x\n"
+ "\n",
+ group_len,
+ sector_size);
+ sector_size = 0;
+ }
- xml_printf(&retval, &xml, &pos, &size,
- "\n" \
- "0x%x\n" \
- "\n", \
- p->base, p->size, blocksize);
ram_start = p->base + p->size;
}
@@ -2197,12 +2212,13 @@ static int gdb_input_inner(struct connection *connection)
log_add_callback(gdb_log_callback, connection);
bool nostep = false;
+ bool already_running = false;
if (target->state == TARGET_RUNNING)
{
- LOG_WARNING("The target is already running. Halt target before stepi/continue.");
- retval = target_halt(target);
- if (retval == ERROR_OK)
- retval = target_wait_state(target, TARGET_HALTED, 100);
+ LOG_WARNING("WARNING! The target is already running. "
+ "All changes GDB did to registers will be discarded! "
+ "Waiting for target to halt.");
+ already_running = true;
} else if (target->state != TARGET_HALTED)
{
LOG_WARNING("The target is not in the halted nor running stated, stepi/continue ignored.");
@@ -2218,7 +2234,7 @@ static int gdb_input_inner(struct connection *connection)
}
gdb_con->sync = false;
- if ((retval!=ERROR_OK) || nostep)
+ if ((retval!=ERROR_OK) || (!already_running && nostep))
{
/* Either the target isn't in the halted state, then we can't
* step/continue. This might be early setup, etc.
@@ -2238,11 +2254,15 @@ static int gdb_input_inner(struct connection *connection)
*/
gdb_con->frontend_state = TARGET_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_GDB_START);
- int retval = gdb_step_continue_packet(connection, target, packet, packet_size);
- if (retval != ERROR_OK)
+
+ if (!already_running)
{
- /* we'll never receive a halted condition... issue a false one.. */
- gdb_frontend_halted(target, connection);
+ int retval = gdb_step_continue_packet(connection, target, packet, packet_size);
+ if (retval != ERROR_OK)
+ {
+ /* we'll never receive a halted condition... issue a false one.. */
+ gdb_frontend_halted(target, connection);
+ }
}
}
}