armv7m_trace: get rid of the old tpiu code
[fw/openocd] / src / target / target.c
index 4ef5ee19ef1bf005062d346619e0fa2b643e2dc0..eb83daebbc8d00ad3a952943bd4c21049d33ee53 100644 (file)
@@ -72,8 +72,6 @@ static int target_get_gdb_fileio_info_default(struct target *target,
                struct gdb_fileio_info *fileio_info);
 static int target_gdb_fileio_end_default(struct target *target, int retcode,
                int fileio_errno, bool ctrl_c);
-static int target_profiling_default(struct target *target, uint32_t *samples,
-               uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);
 
 /* targets */
 extern struct target_type arm7tdmi_target;
@@ -156,8 +154,8 @@ static struct target_type *target_types[] = {
 struct target *all_targets;
 static struct target_event_callback *target_event_callbacks;
 static struct target_timer_callback *target_timer_callbacks;
-LIST_HEAD(target_reset_callback_list);
-LIST_HEAD(target_trace_callback_list);
+static LIST_HEAD(target_reset_callback_list);
+static LIST_HEAD(target_trace_callback_list);
 static const int polling_interval = 100;
 
 static const Jim_Nvp nvp_assert[] = {
@@ -639,7 +637,18 @@ int target_resume(struct target *target, int current, target_addr_t address,
         * we poll. The CPU can even halt at the current PC as a result of
         * a software breakpoint being inserted by (a bug?) the application.
         */
+       /*
+        * resume() triggers the event 'resumed'. The execution of TCL commands
+        * in the event handler causes the polling of targets. If the target has
+        * already halted for a breakpoint, polling will run the 'halted' event
+        * handler before the pending 'resumed' handler.
+        * Disable polling during resume() to guarantee the execution of handlers
+        * in the correct order.
+        */
+       bool save_poll = jtag_poll_get_enabled();
+       jtag_poll_set_enabled(false);
        retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution);
+       jtag_poll_set_enabled(save_poll);
        if (retval != ERROR_OK)
                return retval;
 
@@ -768,9 +777,11 @@ int target_examine(void)
                if (target->defer_examine)
                        continue;
 
-               retval = target_examine_one(target);
-               if (retval != ERROR_OK)
-                       return retval;
+               int retval2 = target_examine_one(target);
+               if (retval2 != ERROR_OK) {
+                       LOG_WARNING("target %s examination failed", target_name(target));
+                       retval = retval2;
+               }
        }
        return retval;
 }
@@ -803,6 +814,13 @@ static int target_soft_reset_halt(struct target *target)
  * algorithm.
  *
  * @param target used to run the algorithm
+ * @param num_mem_params
+ * @param mem_params
+ * @param num_reg_params
+ * @param reg_param
+ * @param entry_point
+ * @param exit_point
+ * @param timeout_ms
  * @param arch_info target-specific description of the algorithm.
  */
 int target_run_algorithm(struct target *target,
@@ -838,6 +856,12 @@ done:
  * Executes a target-specific native code algorithm and leaves it running.
  *
  * @param target used to run the algorithm
+ * @param num_mem_params
+ * @param mem_params
+ * @param num_reg_params
+ * @param reg_params
+ * @param entry_point
+ * @param exit_point
  * @param arch_info target-specific description of the algorithm.
  */
 int target_start_algorithm(struct target *target,
@@ -876,6 +900,12 @@ done:
  * Waits for an algorithm started with target_start_algorithm() to complete.
  *
  * @param target used to run the algorithm
+ * @param num_mem_params
+ * @param mem_params
+ * @param num_reg_params
+ * @param reg_params
+ * @param exit_point
+ * @param timeout_ms
  * @param arch_info target-specific description of the algorithm.
  */
 int target_wait_algorithm(struct target *target,
@@ -947,6 +977,7 @@ done:
  * @param entry_point address on the target to execute to start the algorithm
  * @param exit_point address at which to set a breakpoint to catch the
  *     end of the algorithm; can be 0 if target triggers a breakpoint itself
+ * @param arch_info
  */
 
 int target_run_flash_async_algorithm(struct target *target,
@@ -1031,11 +1062,11 @@ int target_run_flash_async_algorithm(struct target *target,
                         * programming. The exact delay shouldn't matter as long as it's
                         * less than buffer size / flash speed. This is very unlikely to
                         * run when using high latency connections such as USB. */
-                       alive_sleep(10);
+                       alive_sleep(2);
 
                        /* to stop an infinite loop on some targets check and increment a timeout
                         * this issue was observed on a stellaris using the new ICDI interface */
-                       if (timeout++ >= 500) {
+                       if (timeout++ >= 2500) {
                                LOG_ERROR("timeout waiting for algorithm, a target reset is recommended");
                                return ERROR_FLASH_OPERATION_FAILED;
                        }
@@ -1049,6 +1080,10 @@ int target_run_flash_async_algorithm(struct target *target,
                if (thisrun_bytes > count * block_size)
                        thisrun_bytes = count * block_size;
 
+               /* Force end of large blocks to be word aligned */
+               if (thisrun_bytes >= 16)
+                       thisrun_bytes -= (rp + thisrun_bytes) & 0x03;
+
                /* Write data to fifo */
                retval = target_write_buffer(target, wp, thisrun_bytes, buffer);
                if (retval != ERROR_OK)
@@ -1098,6 +1133,156 @@ int target_run_flash_async_algorithm(struct target *target,
        return retval;
 }
 
+int target_run_read_async_algorithm(struct target *target,
+               uint8_t *buffer, uint32_t count, int block_size,
+               int num_mem_params, struct mem_param *mem_params,
+               int num_reg_params, struct reg_param *reg_params,
+               uint32_t buffer_start, uint32_t buffer_size,
+               uint32_t entry_point, uint32_t exit_point, void *arch_info)
+{
+       int retval;
+       int timeout = 0;
+
+       const uint8_t *buffer_orig = buffer;
+
+       /* Set up working area. First word is write pointer, second word is read pointer,
+        * rest is fifo data area. */
+       uint32_t wp_addr = buffer_start;
+       uint32_t rp_addr = buffer_start + 4;
+       uint32_t fifo_start_addr = buffer_start + 8;
+       uint32_t fifo_end_addr = buffer_start + buffer_size;
+
+       uint32_t wp = fifo_start_addr;
+       uint32_t rp = fifo_start_addr;
+
+       /* validate block_size is 2^n */
+       assert(!block_size || !(block_size & (block_size - 1)));
+
+       retval = target_write_u32(target, wp_addr, wp);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = target_write_u32(target, rp_addr, rp);
+       if (retval != ERROR_OK)
+               return retval;
+
+       /* Start up algorithm on target */
+       retval = target_start_algorithm(target, num_mem_params, mem_params,
+                       num_reg_params, reg_params,
+                       entry_point,
+                       exit_point,
+                       arch_info);
+
+       if (retval != ERROR_OK) {
+               LOG_ERROR("error starting target flash read algorithm");
+               return retval;
+       }
+
+       while (count > 0) {
+               retval = target_read_u32(target, wp_addr, &wp);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("failed to get write pointer");
+                       break;
+               }
+
+               LOG_DEBUG("offs 0x%zx count 0x%" PRIx32 " wp 0x%" PRIx32 " rp 0x%" PRIx32,
+                       (size_t)(buffer - buffer_orig), count, wp, rp);
+
+               if (wp == 0) {
+                       LOG_ERROR("flash read algorithm aborted by target");
+                       retval = ERROR_FLASH_OPERATION_FAILED;
+                       break;
+               }
+
+               if (((wp - fifo_start_addr) & (block_size - 1)) || wp < fifo_start_addr || wp >= fifo_end_addr) {
+                       LOG_ERROR("corrupted fifo write pointer 0x%" PRIx32, wp);
+                       break;
+               }
+
+               /* Count the number of bytes available in the fifo without
+                * crossing the wrap around. */
+               uint32_t thisrun_bytes;
+               if (wp >= rp)
+                       thisrun_bytes = wp - rp;
+               else
+                       thisrun_bytes = fifo_end_addr - rp;
+
+               if (thisrun_bytes == 0) {
+                       /* Throttle polling a bit if transfer is (much) faster than flash
+                        * reading. The exact delay shouldn't matter as long as it's
+                        * less than buffer size / flash speed. This is very unlikely to
+                        * run when using high latency connections such as USB. */
+                       alive_sleep(2);
+
+                       /* to stop an infinite loop on some targets check and increment a timeout
+                        * this issue was observed on a stellaris using the new ICDI interface */
+                       if (timeout++ >= 2500) {
+                               LOG_ERROR("timeout waiting for algorithm, a target reset is recommended");
+                               return ERROR_FLASH_OPERATION_FAILED;
+                       }
+                       continue;
+               }
+
+               /* Reset our timeout */
+               timeout = 0;
+
+               /* Limit to the amount of data we actually want to read */
+               if (thisrun_bytes > count * block_size)
+                       thisrun_bytes = count * block_size;
+
+               /* Force end of large blocks to be word aligned */
+               if (thisrun_bytes >= 16)
+                       thisrun_bytes -= (rp + thisrun_bytes) & 0x03;
+
+               /* Read data from fifo */
+               retval = target_read_buffer(target, rp, thisrun_bytes, buffer);
+               if (retval != ERROR_OK)
+                       break;
+
+               /* Update counters and wrap write pointer */
+               buffer += thisrun_bytes;
+               count -= thisrun_bytes / block_size;
+               rp += thisrun_bytes;
+               if (rp >= fifo_end_addr)
+                       rp = fifo_start_addr;
+
+               /* Store updated write pointer to target */
+               retval = target_write_u32(target, rp_addr, rp);
+               if (retval != ERROR_OK)
+                       break;
+
+               /* Avoid GDB timeouts */
+               keep_alive();
+
+       }
+
+       if (retval != ERROR_OK) {
+               /* abort flash write algorithm on target */
+               target_write_u32(target, rp_addr, 0);
+       }
+
+       int retval2 = target_wait_algorithm(target, num_mem_params, mem_params,
+                       num_reg_params, reg_params,
+                       exit_point,
+                       10000,
+                       arch_info);
+
+       if (retval2 != ERROR_OK) {
+               LOG_ERROR("error waiting for target flash write algorithm");
+               retval = retval2;
+       }
+
+       if (retval == ERROR_OK) {
+               /* check if algorithm set wp = 0 after fifo writer loop finished */
+               retval = target_read_u32(target, wp_addr, &wp);
+               if (retval == ERROR_OK && wp == 0) {
+                       LOG_ERROR("flash read algorithm aborted by target");
+                       retval = ERROR_FLASH_OPERATION_FAILED;
+               }
+       }
+
+       return retval;
+}
+
 int target_read_memory(struct target *target,
                target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
@@ -1265,10 +1450,10 @@ int target_get_gdb_reg_list_noread(struct target *target,
 bool target_supports_gdb_connection(struct target *target)
 {
        /*
-        * based on current code, we can simply exclude all the targets that
-        * don't provide get_gdb_reg_list; this could change with new targets.
+        * exclude all the targets that don't provide get_gdb_reg_list
+        * or that have explicit gdb_max_connection == 0
         */
-       return !!target->type->get_gdb_reg_list;
+       return !!target->type->get_gdb_reg_list && !!target->gdb_max_connections;
 }
 
 int target_step(struct target *target,
@@ -1321,13 +1506,9 @@ unsigned target_address_bits(struct target *target)
        return 32;
 }
 
-int target_profiling(struct target *target, uint32_t *samples,
+static int target_profiling(struct target *target, uint32_t *samples,
                        uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
 {
-       if (target->state != TARGET_HALTED) {
-               LOG_WARNING("target %s is not halted (profiling)", target->cmd_name);
-               return ERROR_TARGET_NOT_HALTED;
-       }
        return target->type->profiling(target, samples, max_num_samples,
                        num_samples, seconds);
 }
@@ -1788,10 +1969,8 @@ static void target_split_working_area(struct working_area *area, uint32_t size)
 
                /* If backup memory was allocated to this area, it has the wrong size
                 * now so free it and it will be reallocated if/when needed */
-               if (area->backup) {
-                       free(area->backup);
-                       area->backup = NULL;
-               }
+               free(area->backup);
+               area->backup = NULL;
        }
 }
 
@@ -1811,16 +1990,13 @@ static void target_merge_working_areas(struct target *target)
                        /* Remove the last */
                        struct working_area *to_be_freed = c->next;
                        c->next = c->next->next;
-                       if (to_be_freed->backup)
-                               free(to_be_freed->backup);
+                       free(to_be_freed->backup);
                        free(to_be_freed);
 
                        /* If backup memory was allocated to the remaining area, it's has
                         * the wrong size now */
-                       if (c->backup) {
-                               free(c->backup);
-                               c->backup = NULL;
-                       }
+                       free(c->backup);
+                       c->backup = NULL;
                } else {
                        c = c->next;
                }
@@ -2050,8 +2226,7 @@ static void target_destroy(struct target *target)
        if (target->type->deinit_target)
                target->type->deinit_target(target);
 
-       if (target->semihosting)
-               free(target->semihosting);
+       free(target->semihosting);
 
        jtag_unregister_event_callback(jtag_enable_callback, target);
 
@@ -2147,7 +2322,7 @@ static int target_gdb_fileio_end_default(struct target *target,
        return ERROR_OK;
 }
 
-static int target_profiling_default(struct target *target, uint32_t *samples,
+int target_profiling_default(struct target *target, uint32_t *samples,
                uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
 {
        struct timeval timeout, now;
@@ -2201,7 +2376,7 @@ static int target_profiling_default(struct target *target, uint32_t *samples,
  */
 int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
 {
-       LOG_DEBUG("writing buffer of %" PRIi32 " byte at " TARGET_ADDR_FMT,
+       LOG_DEBUG("writing buffer of %" PRIu32 " byte at " TARGET_ADDR_FMT,
                          size, address);
 
        if (!target_was_examined(target)) {
@@ -2263,7 +2438,7 @@ static int target_write_buffer_default(struct target *target,
  */
 int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
 {
-       LOG_DEBUG("reading buffer of %" PRIi32 " byte at " TARGET_ADDR_FMT,
+       LOG_DEBUG("reading buffer of %" PRIu32 " byte at " TARGET_ADDR_FMT,
                          size, address);
 
        if (!target_was_examined(target)) {
@@ -2333,7 +2508,7 @@ int target_checksum_memory(struct target *target, target_addr_t address, uint32_
        if (retval != ERROR_OK) {
                buffer = malloc(size);
                if (buffer == NULL) {
-                       LOG_ERROR("error allocating buffer for section (%" PRId32 " bytes)", size);
+                       LOG_ERROR("error allocating buffer for section (%" PRIu32 " bytes)", size);
                        return ERROR_COMMAND_SYNTAX_ERROR;
                }
                retval = target_read_buffer(target, address, size, buffer);
@@ -2893,12 +3068,12 @@ COMMAND_HANDLER(handle_reg_command)
                        for (i = 0, reg = cache->reg_list;
                                        i < cache->num_regs;
                                        i++, reg++, count++) {
-                               if (reg->exist == false)
+                               if (reg->exist == false || reg->hidden)
                                        continue;
                                /* only print cached values if they are valid */
                                if (reg->valid) {
-                                       value = buf_to_str(reg->value,
-                                                       reg->size, 16);
+                                       value = buf_to_hex_str(reg->value,
+                                                       reg->size);
                                        command_print(CMD,
                                                        "(%i) %s (/%" PRIu32 "): 0x%s%s",
                                                        count, reg->name,
@@ -2965,7 +3140,7 @@ COMMAND_HANDLER(handle_reg_command)
 
                if (reg->valid == 0)
                        reg->type->get(reg);
-               value = buf_to_str(reg->value, reg->size, 16);
+               value = buf_to_hex_str(reg->value, reg->size);
                command_print(CMD, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value);
                free(value);
                return ERROR_OK;
@@ -2980,7 +3155,7 @@ COMMAND_HANDLER(handle_reg_command)
 
                reg->type->set(reg, buf);
 
-               value = buf_to_str(reg->value, reg->size, 16);
+               value = buf_to_hex_str(reg->value, reg->size);
                command_print(CMD, "%s (/%i): 0x%s", reg->name, (int)(reg->size), value);
                free(value);
 
@@ -3416,11 +3591,11 @@ static COMMAND_HELPER(parse_load_image_command_CMD_ARGV, struct image *image,
                target_addr_t addr;
                COMMAND_PARSE_ADDRESS(CMD_ARGV[1], addr);
                image->base_address = addr;
-               image->base_address_set = 1;
+               image->base_address_set = true;
        } else
-               image->base_address_set = 0;
+               image->base_address_set = false;
 
-       image->start_address_set = 0;
+       image->start_address_set = false;
 
        if (CMD_ARGC >= 4)
                COMMAND_PARSE_ADDRESS(CMD_ARGV[3], *min_address);
@@ -3443,7 +3618,6 @@ COMMAND_HANDLER(handle_load_image_command)
        uint32_t image_size;
        target_addr_t min_address = 0;
        target_addr_t max_address = -1;
-       int i;
        struct image image;
 
        int retval = CALL_COMMAND_HANDLER(parse_load_image_command_CMD_ARGV,
@@ -3461,7 +3635,7 @@ COMMAND_HANDLER(handle_load_image_command)
 
        image_size = 0x0;
        retval = ERROR_OK;
-       for (i = 0; i < image.num_sections; i++) {
+       for (unsigned int i = 0; i < image.num_sections; i++) {
                buffer = malloc(image.sections[i].size);
                if (buffer == NULL) {
                        command_print(CMD,
@@ -3594,7 +3768,6 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver
        uint8_t *buffer;
        size_t buf_cnt;
        uint32_t image_size;
-       int i;
        int retval;
        uint32_t checksum = 0;
        uint32_t mem_checksum = 0;
@@ -3618,13 +3791,13 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver
                target_addr_t addr;
                COMMAND_PARSE_ADDRESS(CMD_ARGV[1], addr);
                image.base_address = addr;
-               image.base_address_set = 1;
+               image.base_address_set = true;
        } else {
-               image.base_address_set = 0;
+               image.base_address_set = false;
                image.base_address = 0x0;
        }
 
-       image.start_address_set = 0;
+       image.start_address_set = false;
 
        retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);
        if (retval != ERROR_OK)
@@ -3633,12 +3806,12 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver
        image_size = 0x0;
        int diffs = 0;
        retval = ERROR_OK;
-       for (i = 0; i < image.num_sections; i++) {
+       for (unsigned int i = 0; i < image.num_sections; i++) {
                buffer = malloc(image.sections[i].size);
                if (buffer == NULL) {
                        command_print(CMD,
-                                       "error allocating buffer for section (%d bytes)",
-                                       (int)(image.sections[i].size));
+                                       "error allocating buffer for section (%" PRIu32 " bytes)",
+                                       image.sections[i].size);
                        break;
                }
                retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);
@@ -3744,8 +3917,8 @@ static int handle_bp_command_list(struct command_invocation *cmd)
        struct breakpoint *breakpoint = target->breakpoints;
        while (breakpoint) {
                if (breakpoint->type == BKPT_SOFT) {
-                       char *buf = buf_to_str(breakpoint->orig_instr,
-                                       breakpoint->length, 16);
+                       char *buf = buf_to_hex_str(breakpoint->orig_instr,
+                                       breakpoint->length);
                        command_print(cmd, "IVA breakpoint: " TARGET_ADDR_FMT ", 0x%x, %i, 0x%s",
                                        breakpoint->address,
                                        breakpoint->length,
@@ -3894,7 +4067,7 @@ COMMAND_HANDLER(handle_wp_command)
        }
 
        enum watchpoint_rw type = WPT_ACCESS;
-       uint32_t addr = 0;
+       target_addr_t addr = 0;
        uint32_t length = 0;
        uint32_t data_value = 0x0;
        uint32_t data_mask = 0xffffffff;
@@ -3924,7 +4097,7 @@ COMMAND_HANDLER(handle_wp_command)
                /* fall through */
        case 2:
                COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);
-               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
+               COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
                break;
 
        default:
@@ -3944,8 +4117,8 @@ COMMAND_HANDLER(handle_rwp_command)
        if (CMD_ARGC != 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       uint32_t addr;
-       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr);
+       target_addr_t addr;
+       COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
 
        struct target *target = get_current_target(CMD_CTX);
        watchpoint_remove(target, addr);
@@ -4109,6 +4282,7 @@ COMMAND_HANDLER(handle_profile_command)
        uint32_t offset;
        uint32_t num_of_samples;
        int retval = ERROR_OK;
+       bool halted_before_profiling = target->state == TARGET_HALTED;
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], offset);
 
@@ -4139,12 +4313,23 @@ COMMAND_HANDLER(handle_profile_command)
                free(samples);
                return retval;
        }
-       if (target->state == TARGET_RUNNING) {
+
+       if (target->state == TARGET_RUNNING && halted_before_profiling) {
+               /* The target was halted before we started and is running now. Halt it,
+                * for consistency. */
                retval = target_halt(target);
                if (retval != ERROR_OK) {
                        free(samples);
                        return retval;
                }
+       } else if (target->state == TARGET_HALTED && !halted_before_profiling) {
+               /* The target was running before we started and is halted now. Resume
+                * it, for consistency. */
+               retval = target_resume(target, 1, 0, 0, 0);
+               if (retval != ERROR_OK) {
+                       free(samples);
+                       return retval;
+               }
        }
 
        retval = target_poll(target);
@@ -4301,7 +4486,7 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc,
        } else {
                char buf[100];
                Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-               sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads",
+               sprintf(buf, "mem2array address: 0x%08" PRIx32 " is not aligned for %" PRIu32 " byte reads",
                                addr,
                                width);
                Jim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL);
@@ -4333,7 +4518,7 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc,
                        retval = target_read_memory(target, addr, width, count, buffer);
                if (retval != ERROR_OK) {
                        /* BOO !*/
-                       LOG_ERROR("mem2array: Read @ 0x%08" PRIx32 ", w=%" PRId32 ", cnt=%" PRId32 ", failed",
+                       LOG_ERROR("mem2array: Read @ 0x%08" PRIx32 ", w=%" PRIu32 ", cnt=%" PRIu32 ", failed",
                                          addr,
                                          width,
                                          count);
@@ -4507,7 +4692,7 @@ static int target_array2mem(Jim_Interp *interp, struct target *target,
        } else {
                char buf[100];
                Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-               sprintf(buf, "array2mem address: 0x%08" PRIx32 " is not aligned for %" PRId32 " byte reads",
+               sprintf(buf, "array2mem address: 0x%08" PRIx32 " is not aligned for %" PRIu32 " byte reads",
                                addr,
                                width);
                Jim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL);
@@ -4556,7 +4741,7 @@ static int target_array2mem(Jim_Interp *interp, struct target *target,
                        retval = target_write_memory(target, addr, width, count, buffer);
                if (retval != ERROR_OK) {
                        /* BOO !*/
-                       LOG_ERROR("array2mem: Write @ 0x%08" PRIx32 ", w=%" PRId32 ", cnt=%" PRId32 ", failed",
+                       LOG_ERROR("array2mem: Write @ 0x%08" PRIx32 ", w=%" PRIu32 ", cnt=%" PRIu32 ", failed",
                                          addr,
                                          width,
                                          count);
@@ -4652,6 +4837,7 @@ enum target_cfg_param {
        TCFG_RTOS,
        TCFG_DEFER_EXAMINE,
        TCFG_GDB_PORT,
+       TCFG_GDB_MAX_CONNECTIONS,
 };
 
 static Jim_Nvp nvp_config_opts[] = {
@@ -4668,6 +4854,7 @@ static Jim_Nvp nvp_config_opts[] = {
        { .name = "-rtos",             .value = TCFG_RTOS },
        { .name = "-defer-examine",    .value = TCFG_DEFER_EXAMINE },
        { .name = "-gdb-port",         .value = TCFG_GDB_PORT },
+       { .name = "-gdb-max-connections",   .value = TCFG_GDB_MAX_CONNECTIONS },
        { .name = NULL, .value = -1 }
 };
 
@@ -4758,6 +4945,11 @@ no_params:
                                }
 
                                if (goi->isconfigure) {
+                                       /* START_DEPRECATED_TPIU */
+                                       if (n->value == TARGET_EVENT_TRACE_CONFIG)
+                                               LOG_INFO("DEPRECATED target event %s", n->name);
+                                       /* END_DEPRECATED_TPIU */
+
                                        bool replace = true;
                                        if (teap == NULL) {
                                                /* create new */
@@ -4967,6 +5159,7 @@ no_params:
                                e = Jim_GetOpt_String(goi, &s, NULL);
                                if (e != JIM_OK)
                                        return e;
+                               free(target->gdb_port_override);
                                target->gdb_port_override = strdup(s);
                        } else {
                                if (goi->argc != 0)
@@ -4975,6 +5168,25 @@ no_params:
                        Jim_SetResultString(goi->interp, target->gdb_port_override ? : "undefined", -1);
                        /* loop for more */
                        break;
+
+               case TCFG_GDB_MAX_CONNECTIONS:
+                       if (goi->isconfigure) {
+                               struct command_context *cmd_ctx = current_command_context(goi->interp);
+                               if (cmd_ctx->mode != COMMAND_CONFIG) {
+                                       Jim_SetResultString(goi->interp, "-gdb-max-conenctions must be configured before 'init'", -1);
+                                       return JIM_ERR;
+                               }
+
+                               e = Jim_GetOpt_Wide(goi, &w);
+                               if (e != JIM_OK)
+                                       return e;
+                               target->gdb_max_connections = (w < 0) ? CONNECTION_LIMIT_UNLIMITED : (int)w;
+                       } else {
+                               if (goi->argc != 0)
+                                       goto no_params;
+                       }
+                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->gdb_max_connections));
+                       break;
                }
        } /* while (goi->argc) */
 
@@ -5514,9 +5726,6 @@ static int target_create(Jim_GetOptInfo *goi)
 
        memcpy(target->type, target_types[x], sizeof(struct target_type));
 
-       /* will be set by "-endian" */
-       target->endianness = TARGET_ENDIAN_UNKNOWN;
-
        /* default to first core, override with -coreid */
        target->coreid = 0;
 
@@ -5555,6 +5764,7 @@ static int target_create(Jim_GetOptInfo *goi)
        target->rtos_auto_detect = false;
 
        target->gdb_port_override = NULL;
+       target->gdb_max_connections = 1;
 
        /* Do the rest as "configure" options */
        goi->isconfigure = 1;
@@ -5677,7 +5887,9 @@ static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv
        struct command_context *cmd_ctx = current_command_context(interp);
        assert(cmd_ctx != NULL);
 
-       Jim_SetResultString(interp, target_name(get_current_target(cmd_ctx)), -1);
+       struct target *target = get_current_target_or_null(cmd_ctx);
+       if (target)
+               Jim_SetResultString(interp, target_name(target), -1);
        return JIM_OK;
 }
 
@@ -5833,11 +6045,8 @@ static struct FastLoad *fastload;
 static void free_fastload(void)
 {
        if (fastload != NULL) {
-               int i;
-               for (i = 0; i < fastload_num; i++) {
-                       if (fastload[i].data)
-                               free(fastload[i].data);
-               }
+               for (int i = 0; i < fastload_num; i++)
+                       free(fastload[i].data);
                free(fastload);
                fastload = NULL;
        }
@@ -5850,7 +6059,6 @@ COMMAND_HANDLER(handle_fast_load_image_command)
        uint32_t image_size;
        target_addr_t min_address = 0;
        target_addr_t max_address = -1;
-       int i;
 
        struct image image;
 
@@ -5876,7 +6084,7 @@ COMMAND_HANDLER(handle_fast_load_image_command)
                return ERROR_FAIL;
        }
        memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
-       for (i = 0; i < image.num_sections; i++) {
+       for (unsigned int i = 0; i < image.num_sections; i++) {
                buffer = malloc(image.sections[i].size);
                if (buffer == NULL) {
                        command_print(CMD, "error allocating buffer for section (%d bytes)",