+ /* We get away with only specifying flash here. Regions that are not
+ * specified are treated as if we provided no memory map(if not we
+ * could detect the holes and mark them as RAM).
+ * Normally we only execute this code once, but no big deal if we
+ * have to regenerate it a couple of times.
+ */
+
+ struct flash_bank *p;
+ char *xml = NULL;
+ int size = 0;
+ int pos = 0;
+ int retval = ERROR_OK;
+ struct flash_bank **banks;
+ int offset;
+ int length;
+ char *separator;
+ uint32_t ram_start = 0;
+ int i;
+ int target_flash_banks = 0;
+
+ /* skip command character */
+ packet += 23;
+
+ offset = strtoul(packet, &separator, 16);
+ length = strtoul(separator + 1, &separator, 16);
+
+ xml_printf(&retval, &xml, &pos, &size, "<memory-map>\n");
+
+ /* Sort banks in ascending order. We need to report non-flash
+ * memory as ram (or rather read/write) by default for GDB, since
+ * 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());
+
+ for (i = 0; i < flash_get_bank_count(); i++) {
+ retval = get_flash_bank_by_num(i, &p);
+ if (retval != ERROR_OK)
+ {
+ free(banks);
+ gdb_error(connection, retval);
+ return retval;
+ }
+ if(p->target == target)
+ banks[target_flash_banks++] = p;
+ }
+
+ qsort(banks, target_flash_banks, sizeof(struct flash_bank *),
+ 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,
+ "<memory type=\"ram\" start=\"0x%x\" "
+ "length=\"0x%x\"/>\n",
+ ram_start, p->base - ram_start);
+
+ /* 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.
+ */
+ 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,
+ "<memory type=\"flash\" "
+ "start=\"0x%x\" ",
+ start);
+ sector_size = p->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"
+ "<property name=\"blocksize\">"
+ "0x%x</property>\n"
+ "</memory>\n",
+ group_len,
+ sector_size);
+ sector_size = 0;
+ }
+
+ ram_start = p->base + p->size;
+ }
+
+ if (ram_start != 0)
+ xml_printf(&retval, &xml, &pos, &size,
+ "<memory type=\"ram\" start=\"0x%x\" "
+ "length=\"0x%x\"/>\n",
+ ram_start, 0-ram_start);
+ /* ELSE a flash chip could be at the very end of the 32 bit address
+ * space, in which case ram_start will be precisely 0
+ */
+
+ free(banks);
+ banks = NULL;
+
+ xml_printf(&retval, &xml, &pos, &size, "</memory-map>\n");
+
+ if (retval != ERROR_OK) {
+ gdb_error(connection, retval);
+ return retval;
+ }
+
+ if (offset + length > pos)
+ length = pos - offset;
+
+ char *t = malloc(length + 1);
+ t[0] = 'l';
+ memcpy(t + 1, xml + offset, length);
+ gdb_put_packet(connection, t, length + 1);
+
+ free(t);
+ free(xml);
+ return ERROR_OK;
+}
+
+static int gdb_query_packet(struct connection *connection,
+ struct target *target, char *packet, int packet_size)
+{
+ struct command_context *cmd_ctx = connection->cmd_ctx;
+ struct gdb_connection *gdb_connection = connection->priv;