* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "image.h"
#include "rtos/rtos.h"
+/* default halt wait timeout (ms) */
+#define DEFAULT_HALT_TIMEOUT 5000
+
static int target_read_buffer_default(struct target *target, uint32_t address,
- uint32_t size, uint8_t *buffer);
+ uint32_t count, uint8_t *buffer);
static int target_write_buffer_default(struct target *target, uint32_t address,
- uint32_t size, const uint8_t *buffer);
+ uint32_t count, const uint8_t *buffer);
static int target_array2mem(Jim_Interp *interp, struct target *target,
int argc, Jim_Obj * const *argv);
static int target_mem2array(Jim_Interp *interp, struct target *target,
int argc, Jim_Obj * const *argv);
static int target_register_user_commands(struct command_context *cmd_ctx);
+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);
/* targets */
extern struct target_type arm7tdmi_target;
extern struct target_type xscale_target;
extern struct target_type cortexm3_target;
extern struct target_type cortexa8_target;
+extern struct target_type cortexr4_target;
extern struct target_type arm11_target;
extern struct target_type mips_m4k_target;
extern struct target_type avr_target;
extern struct target_type dsp5680xx_target;
extern struct target_type testee_target;
extern struct target_type avr32_ap7k_target;
-extern struct target_type stm32_stlink_target;
+extern struct target_type hla_target;
+extern struct target_type nds32_v2_target;
+extern struct target_type nds32_v3_target;
+extern struct target_type nds32_v3m_target;
static struct target_type *target_types[] = {
&arm7tdmi_target,
&xscale_target,
&cortexm3_target,
&cortexa8_target,
+ &cortexr4_target,
&arm11_target,
&mips_m4k_target,
&avr_target,
&dsp5680xx_target,
&testee_target,
&avr32_ap7k_target,
- &stm32_stlink_target,
+ &hla_target,
+ &nds32_v2_target,
+ &nds32_v3_target,
+ &nds32_v3m_target,
NULL,
};
}
static const Jim_Nvp nvp_target_event[] = {
- { .value = TARGET_EVENT_OLD_gdb_program_config , .name = "old-gdb_program_config" },
- { .value = TARGET_EVENT_OLD_pre_resume , .name = "old-pre_resume" },
{ .value = TARGET_EVENT_GDB_HALT, .name = "gdb-halt" },
{ .value = TARGET_EVENT_HALTED, .name = "halted" },
{ .name = "gdb-start", .value = TARGET_EVENT_GDB_START },
{ .name = "gdb-end", .value = TARGET_EVENT_GDB_END },
- /* historical name */
-
- { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
-
+ { .value = TARGET_EVENT_RESET_START, .name = "reset-start" },
{ .value = TARGET_EVENT_RESET_ASSERT_PRE, .name = "reset-assert-pre" },
{ .value = TARGET_EVENT_RESET_ASSERT, .name = "reset-assert" },
{ .value = TARGET_EVENT_RESET_ASSERT_POST, .name = "reset-assert-post" },
{ .name = "watchpoint-and-breakpoint", .value = DBG_REASON_WPTANDBKPT },
{ .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
{ .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
+ { .name = "program-exit" , .value = DBG_REASON_EXIT },
{ .name = "undefined" , .value = DBG_REASON_UNDEFINED },
{ .name = NULL, .value = -1 },
};
/* try as tcltarget name */
for (target = all_targets; target; target = target->next) {
- if (target->cmd_name == NULL)
+ if (target_name(target) == NULL)
continue;
- if (strcmp(id, target->cmd_name) == 0)
+ if (strcmp(id, target_name(target)) == 0)
return target;
}
for (target = all_targets; target; target = target->next) {
if (target->target_number == (int)num) {
LOG_WARNING("use '%s' as target identifier, not '%u'",
- target->cmd_name, num);
+ target_name(target), num);
return target;
}
}
target->halt_issued = false;
else {
long long t = timeval_ms() - target->halt_issued_time;
- if (t > 1000) {
+ if (t > DEFAULT_HALT_TIMEOUT) {
target->halt_issued = false;
LOG_INFO("Halt timed out, wake up GDB.");
target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
return ERROR_FAIL;
}
+ target_call_event_callbacks(target, TARGET_EVENT_RESUME_START);
+
/* note that resume *must* be asynchronous. The CPU can halt before
* 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.
if (retval != ERROR_OK)
return retval;
+ target_call_event_callbacks(target, TARGET_EVENT_RESUME_END);
+
return retval;
}
retval = target_call_timer_callbacks_now();
struct target *target;
- for (target = all_targets; target; target = target->next)
+ for (target = all_targets; target; target = target->next) {
target->type->check_reset(target);
+ target->running_alg = false;
+ }
return retval;
}
return ERROR_OK;
jtag_unregister_event_callback(jtag_enable_callback, target);
- return target_examine_one(target);
-}
+ target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_START);
+
+ int retval = target_examine_one(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END);
+
+ return retval;
+}
/* Targets that correctly implement init + examine, i.e.
* no communication with target during init:
target);
continue;
}
+
+ target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_START);
+
retval = target_examine_one(target);
if (retval != ERROR_OK)
return retval;
+
+ target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END);
}
return retval;
}
+
const char *target_type_name(struct target *target)
{
return target->type->name;
}
-static int target_write_memory_imp(struct target *target, uint32_t address,
- uint32_t size, uint32_t count, const uint8_t *buffer)
-{
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
- return target->type->write_memory_imp(target, address, size, count, buffer);
-}
-
-static int target_read_memory_imp(struct target *target, uint32_t address,
- uint32_t size, uint32_t count, uint8_t *buffer)
+static int target_soft_reset_halt(struct target *target)
{
if (!target_was_examined(target)) {
LOG_ERROR("Target not examined yet");
return ERROR_FAIL;
}
- return target->type->read_memory_imp(target, address, size, count, buffer);
-}
-
-static int target_soft_reset_halt_imp(struct target *target)
-{
- if (!target_was_examined(target)) {
- LOG_ERROR("Target not examined yet");
- return ERROR_FAIL;
- }
- if (!target->type->soft_reset_halt_imp) {
+ if (!target->type->soft_reset_halt) {
LOG_ERROR("Target %s does not support soft_reset_halt",
target_name(target));
return ERROR_FAIL;
}
- return target->type->soft_reset_halt_imp(target);
+ return target->type->soft_reset_halt(target);
}
/**
uint32_t entry_point, uint32_t exit_point, void *arch_info)
{
int retval;
+ int timeout = 0;
/* Set up working area. First word is write pointer, second word is read pointer,
* rest is fifo data area. */
* less than buffer size / flash speed. This is very unlikely to
* run when using high latency connections such as USB. */
alive_sleep(10);
+
+ /* 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) {
+ 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 write */
if (thisrun_bytes > count * block_size)
thisrun_bytes = count * block_size;
int target_read_memory(struct target *target,
uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
{
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
return target->type->read_memory(target, address, size, count, buffer);
}
-static int target_read_phys_memory(struct target *target,
+int target_read_phys_memory(struct target *target,
uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
{
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
return target->type->read_phys_memory(target, address, size, count, buffer);
}
int target_write_memory(struct target *target,
uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
return target->type->write_memory(target, address, size, count, buffer);
}
-static int target_write_phys_memory(struct target *target,
+int target_write_phys_memory(struct target *target,
uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
return target->type->write_phys_memory(target, address, size, count, buffer);
}
-int target_bulk_write_memory(struct target *target,
- uint32_t address, uint32_t count, const uint8_t *buffer)
-{
- return target->type->bulk_write_memory(target, address, count, buffer);
-}
-
int target_add_breakpoint(struct target *target,
struct breakpoint *breakpoint)
{
if ((target->state != TARGET_HALTED) && (breakpoint->type != BKPT_HARD)) {
- LOG_WARNING("target %s is not halted", target->cmd_name);
+ LOG_WARNING("target %s is not halted", target_name(target));
return ERROR_TARGET_NOT_HALTED;
}
return target->type->add_breakpoint(target, breakpoint);
struct breakpoint *breakpoint)
{
if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target->cmd_name);
+ LOG_WARNING("target %s is not halted", target_name(target));
return ERROR_TARGET_NOT_HALTED;
}
return target->type->add_context_breakpoint(target, breakpoint);
struct breakpoint *breakpoint)
{
if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target->cmd_name);
+ LOG_WARNING("target %s is not halted", target_name(target));
return ERROR_TARGET_NOT_HALTED;
}
return target->type->add_hybrid_breakpoint(target, breakpoint);
struct watchpoint *watchpoint)
{
if (target->state != TARGET_HALTED) {
- LOG_WARNING("target %s is not halted", target->cmd_name);
+ LOG_WARNING("target %s is not halted", target_name(target));
return ERROR_TARGET_NOT_HALTED;
}
return target->type->add_watchpoint(target, watchpoint);
{
return target->type->remove_watchpoint(target, watchpoint);
}
+int target_hit_watchpoint(struct target *target,
+ struct watchpoint **hit_watchpoint)
+{
+ if (target->state != TARGET_HALTED) {
+ LOG_WARNING("target %s is not halted", target->cmd_name);
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (target->type->hit_watchpoint == NULL) {
+ /* For backward compatible, if hit_watchpoint is not implemented,
+ * return ERROR_FAIL such that gdb_server will not take the nonsense
+ * information. */
+ return ERROR_FAIL;
+ }
+
+ return target->type->hit_watchpoint(target, hit_watchpoint);
+}
int target_get_gdb_reg_list(struct target *target,
- struct reg **reg_list[], int *reg_list_size)
+ struct reg **reg_list[], int *reg_list_size,
+ enum target_register_class reg_class)
{
- return target->type->get_gdb_reg_list(target, reg_list, reg_list_size);
+ return target->type->get_gdb_reg_list(target, reg_list, reg_list_size, reg_class);
}
int target_step(struct target *target,
int current, uint32_t address, int handle_breakpoints)
return target->type->step(target, current, address, handle_breakpoints);
}
+int target_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)
+{
+ if (target->state != TARGET_HALTED) {
+ LOG_WARNING("target %s is not halted", target->cmd_name);
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->get_gdb_fileio_info(target, fileio_info);
+}
+
+int target_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c)
+{
+ if (target->state != TARGET_HALTED) {
+ LOG_WARNING("target %s is not halted", target->cmd_name);
+ return ERROR_TARGET_NOT_HALTED;
+ }
+ return target->type->gdb_fileio_end(target, retcode, fileio_errno, ctrl_c);
+}
+
/**
* Reset the @c examined flag for the given target.
* Pure paranoia -- targets are zeroed on allocation.
return retval;
}
- /**
- * @todo get rid of those *memory_imp() methods, now that all
- * callers are using target_*_memory() accessors ... and make
- * sure the "physical" paths handle the same issues.
- */
- /* a non-invasive way(in terms of patches) to add some code that
- * runs before the type->write/read_memory implementation
- */
- type->write_memory_imp = target->type->write_memory;
- type->write_memory = target_write_memory_imp;
-
- type->read_memory_imp = target->type->read_memory;
- type->read_memory = target_read_memory_imp;
-
- type->soft_reset_halt_imp = target->type->soft_reset_halt;
- type->soft_reset_halt = target_soft_reset_halt_imp;
-
/* Sanity-check MMU support ... stub in what we must, to help
* implement it in stages, but warn if we need to do so.
*/
if (target->type->write_buffer == NULL)
target->type->write_buffer = target_write_buffer_default;
+ if (target->type->get_gdb_fileio_info == NULL)
+ target->type->get_gdb_fileio_info = target_get_gdb_fileio_info_default;
+
+ if (target->type->gdb_fileio_end == NULL)
+ target->type->gdb_fileio_end = target_gdb_fileio_end_default;
+
return ERROR_OK;
}
return retval;
}
+static int target_get_gdb_fileio_info_default(struct target *target,
+ struct gdb_fileio_info *fileio_info)
+{
+ /* If target does not support semi-hosting function, target
+ has no need to provide .get_gdb_fileio_info callback.
+ It just return ERROR_FAIL and gdb_server will return "Txx"
+ as target halted every time. */
+ return ERROR_FAIL;
+}
+
+static int target_gdb_fileio_end_default(struct target *target,
+ int retcode, int fileio_errno, bool ctrl_c)
+{
+ return ERROR_OK;
+}
+
/* Single aligned words are guaranteed to use 16 or 32 bit access
* mode respectively, otherwise data is handled as quickly as
* possible
return target->type->write_buffer(target, address, size, buffer);
}
-static int target_write_buffer_default(struct target *target, uint32_t address, uint32_t size, const uint8_t *buffer)
+static int target_write_buffer_default(struct target *target, uint32_t address, uint32_t count, const uint8_t *buffer)
{
- int retval = ERROR_OK;
-
- if (((address % 2) == 0) && (size == 2))
- return target_write_memory(target, address, 2, 1, buffer);
-
- /* handle unaligned head bytes */
- if (address % 4) {
- uint32_t unaligned = 4 - (address % 4);
+ uint32_t size;
- if (unaligned > size)
- unaligned = size;
-
- retval = target_write_memory(target, address, 1, unaligned, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- buffer += unaligned;
- address += unaligned;
- size -= unaligned;
- }
-
- /* handle aligned words */
- if (size >= 4) {
- int aligned = size - (size % 4);
-
- /* use bulk writes above a certain limit. This may have to be changed */
- if (aligned > 128) {
- retval = target->type->bulk_write_memory(target, address, aligned / 4, buffer);
- if (retval != ERROR_OK)
- return retval;
- } else {
- retval = target_write_memory(target, address, 4, aligned / 4, buffer);
+ /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
+ * will have something to do with the size we leave to it. */
+ for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
+ if (address & size) {
+ int retval = target_write_memory(target, address, size, 1, buffer);
if (retval != ERROR_OK)
return retval;
+ address += size;
+ count -= size;
+ buffer += size;
}
-
- buffer += aligned;
- address += aligned;
- size -= aligned;
}
- /* handle tail writes of less than 4 bytes */
- if (size > 0) {
- retval = target_write_memory(target, address, 1, size, buffer);
- if (retval != ERROR_OK)
- return retval;
+ /* Write the data with as large access size as possible. */
+ for (; size > 0; size /= 2) {
+ uint32_t aligned = count - count % size;
+ if (aligned > 0) {
+ int retval = target_write_memory(target, address, size, aligned / size, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += aligned;
+ count -= aligned;
+ buffer += aligned;
+ }
}
- return retval;
+ return ERROR_OK;
}
/* Single aligned words are guaranteed to use 16 or 32 bit access
return target->type->read_buffer(target, address, size, buffer);
}
-static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
+static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)
{
- int retval = ERROR_OK;
-
- if (((address % 2) == 0) && (size == 2))
- return target_read_memory(target, address, 2, 1, buffer);
-
- /* handle unaligned head bytes */
- if (address % 4) {
- uint32_t unaligned = 4 - (address % 4);
+ uint32_t size;
- if (unaligned > size)
- unaligned = size;
-
- retval = target_read_memory(target, address, 1, unaligned, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- buffer += unaligned;
- address += unaligned;
- size -= unaligned;
- }
-
- /* handle aligned words */
- if (size >= 4) {
- int aligned = size - (size % 4);
-
- retval = target_read_memory(target, address, 4, aligned / 4, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- buffer += aligned;
- address += aligned;
- size -= aligned;
+ /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
+ * will have something to do with the size we leave to it. */
+ for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
+ if (address & size) {
+ int retval = target_read_memory(target, address, size, 1, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += size;
+ count -= size;
+ buffer += size;
+ }
}
- /*prevent byte access when possible (avoid AHB access limitations in some cases)*/
- if (size >= 2) {
- int aligned = size - (size % 2);
- retval = target_read_memory(target, address, 2, aligned / 2, buffer);
- if (retval != ERROR_OK)
- return retval;
-
- buffer += aligned;
- address += aligned;
- size -= aligned;
- }
- /* handle tail writes of less than 4 bytes */
- if (size > 0) {
- retval = target_read_memory(target, address, 1, size, buffer);
- if (retval != ERROR_OK)
- return retval;
+ /* Read the data with as large access size as possible. */
+ for (; size > 0; size /= 2) {
+ uint32_t aligned = count - count % size;
+ if (aligned > 0) {
+ int retval = target_read_memory(target, address, size, aligned / size, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += aligned;
+ count -= aligned;
+ buffer += aligned;
+ }
}
return ERROR_OK;
return ERROR_OK;
}
-static int backoff_times;
-static int backoff_count;
-
/* process target state changes */
static int handle_target(void *priv)
{
recursive = 0;
}
- if (backoff_times > backoff_count) {
- /* do not poll this time as we failed previously */
- backoff_count++;
- return ERROR_OK;
- }
- backoff_count = 0;
-
/* Poll targets for state changes unless that's globally disabled.
* Skip targets that are currently disabled.
*/
if (!target->tap->enabled)
continue;
+ if (target->backoff.times > target->backoff.count) {
+ /* do not poll this time as we failed previously */
+ target->backoff.count++;
+ continue;
+ }
+ target->backoff.count = 0;
+
/* only poll target if we've got power and srst isn't asserted */
if (!powerDropout && !srstAsserted) {
/* polling may fail silently until the target has been examined */
retval = target_poll(target);
if (retval != ERROR_OK) {
/* 100ms polling interval. Increase interval between polling up to 5000ms */
- if (backoff_times * polling_interval < 5000) {
- backoff_times *= 2;
- backoff_times++;
+ if (target->backoff.times * polling_interval < 5000) {
+ target->backoff.times *= 2;
+ target->backoff.times++;
}
- LOG_USER("Polling target failed, GDB will be halted. Polling again in %dms",
- backoff_times * polling_interval);
+ LOG_USER("Polling target %s failed, GDB will be halted. Polling again in %dms",
+ target_name(target),
+ target->backoff.times * polling_interval);
/* Tell GDB to halt the debugger. This allows the user to
* run monitor commands to handle the situation.
return retval;
}
/* Since we succeeded, we reset backoff count */
- if (backoff_times > 0)
- LOG_USER("Polling succeeded again");
- backoff_times = 0;
+ if (target->backoff.times > 0)
+ LOG_USER("Polling target %s succeeded again", target_name(target));
+ target->backoff.times = 0;
}
}
if (CMD_ARGC > 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- unsigned ms = 5000;
+ unsigned ms = DEFAULT_HALT_TIMEOUT;
if (1 == CMD_ARGC) {
int retval = parse_uint(CMD_ARGV[0], &ms);
if (ERROR_OK != retval)
return ERROR_COMMAND_SYNTAX_ERROR;
- /* convert seconds (given) to milliseconds (needed) */
- ms *= 1000;
}
struct target *target = get_current_target(CMD_CTX);
LOG_USER("requesting target halt and executing a soft reset");
- target->type->soft_reset_halt(target);
+ target_soft_reset_halt(target);
return ERROR_OK;
}
return ERROR_COMMAND_SYNTAX_ERROR;
struct target *target = get_current_target(CMD_CTX);
- target_handle_event(target, TARGET_EVENT_OLD_pre_resume);
/* with no CMD_ARGV, resume from current pc, addr = 0,
* with one arguments, addr = CMD_ARGV[0],
return (target_fill_mem(target, a, fn, data_size, b, c) == ERROR_OK) ? JIM_OK : JIM_ERR;
}
+/**
+* @brief Reads an array of words/halfwords/bytes from target memory starting at specified address.
+*
+* Usage: mdw [phys] <address> [<count>] - for 32 bit reads
+* mdh [phys] <address> [<count>] - for 16 bit reads
+* mdb [phys] <address> [<count>] - for 8 bit reads
+*
+* Count defaults to 1.
+*
+* Calls target_read_memory or target_read_phys_memory depending on
+* the presence of the "phys" argument
+* Reads the target memory in blocks of max. 32 bytes, and returns an array of ints formatted
+* to int representation in base16.
+* Also outputs read data in a human readable form using command_print
+*
+* @param phys if present target_read_phys_memory will be used instead of target_read_memory
+* @param address address where to start the read. May be specified in decimal or hex using the standard "0x" prefix
+* @param count optional count parameter to read an array of values. If not specified, defaults to 1.
+* @returns: JIM_ERR on error or JIM_OK on success and sets the result string to an array of ascii formatted numbers
+* on success, with [<count>] number of elements.
+*
+* In case of little endian target:
+* Example1: "mdw 0x00000000" returns "10123456"
+* Exmaple2: "mdh 0x00000000 1" returns "3456"
+* Example3: "mdb 0x00000000" returns "56"
+* Example4: "mdh 0x00000000 2" returns "3456 1012"
+* Example5: "mdb 0x00000000 3" returns "56 34 12"
+**/
static int jim_target_md(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
const char *cmd_name = Jim_GetString(argv[0], NULL);
fn = target_read_phys_memory;
}
- jim_wide a;
- e = Jim_GetOpt_Wide(&goi, &a);
+ /* Read address parameter */
+ jim_wide addr;
+ e = Jim_GetOpt_Wide(&goi, &addr);
if (e != JIM_OK)
return JIM_ERR;
- jim_wide c;
+
+ /* If next parameter exists, read it out as the count parameter, if not, set it to 1 (default) */
+ jim_wide count;
if (goi.argc == 1) {
- e = Jim_GetOpt_Wide(&goi, &c);
+ e = Jim_GetOpt_Wide(&goi, &count);
if (e != JIM_OK)
return JIM_ERR;
} else
- c = 1;
+ count = 1;
/* all args must be consumed */
if (goi.argc != 0)
return JIM_ERR;
- jim_wide b = 1; /* shut up gcc */
+ jim_wide dwidth = 1; /* shut up gcc */
if (strcasecmp(cmd_name, "mdw") == 0)
- b = 4;
+ dwidth = 4;
else if (strcasecmp(cmd_name, "mdh") == 0)
- b = 2;
+ dwidth = 2;
else if (strcasecmp(cmd_name, "mdb") == 0)
- b = 1;
+ dwidth = 1;
else {
LOG_ERROR("command '%s' unknown: ", cmd_name);
return JIM_ERR;
}
/* convert count to "bytes" */
- c = c * b;
+ int bytes = count * dwidth;
struct target *target = Jim_CmdPrivData(goi.interp);
uint8_t target_buf[32];
jim_wide x, y, z;
- while (c > 0) {
- y = c;
- if (y > 16)
- y = 16;
- e = fn(target, a, b, y / b, target_buf);
+ while (bytes > 0) {
+ y = (bytes < 16) ? bytes : 16; /* y = min(bytes, 16); */
+
+ /* Try to read out next block */
+ e = fn(target, addr, dwidth, y / dwidth, target_buf);
+
if (e != ERROR_OK) {
- char tmp[10];
- snprintf(tmp, sizeof(tmp), "%08lx", (long)a);
- Jim_SetResultFormatted(interp, "error reading target @ 0x%s", tmp);
+ Jim_SetResultFormatted(interp, "error reading target @ 0x%08lx", (long)addr);
return JIM_ERR;
}
- command_print(NULL, "0x%08x ", (int)(a));
- switch (b) {
+ command_print_sameline(NULL, "0x%08x ", (int)(addr));
+ switch (dwidth) {
case 4:
for (x = 0; x < 16 && x < y; x += 4) {
z = target_buffer_get_u32(target, &(target_buf[x]));
- command_print(NULL, "%08x ", (int)(z));
+ command_print_sameline(NULL, "%08x ", (int)(z));
}
for (; (x < 16) ; x += 4)
- command_print(NULL, " ");
+ command_print_sameline(NULL, " ");
break;
case 2:
for (x = 0; x < 16 && x < y; x += 2) {
z = target_buffer_get_u16(target, &(target_buf[x]));
- command_print(NULL, "%04x ", (int)(z));
+ command_print_sameline(NULL, "%04x ", (int)(z));
}
for (; (x < 16) ; x += 2)
- command_print(NULL, " ");
+ command_print_sameline(NULL, " ");
break;
case 1:
default:
for (x = 0 ; (x < 16) && (x < y) ; x += 1) {
z = target_buffer_get_u8(target, &(target_buf[x]));
- command_print(NULL, "%02x ", (int)(z));
+ command_print_sameline(NULL, "%02x ", (int)(z));
}
for (; (x < 16) ; x += 1)
- command_print(NULL, " ");
+ command_print_sameline(NULL, " ");
break;
}
/* ascii-ify the bytes */
/* terminate */
target_buf[16] = 0;
/* print - with a newline */
- command_print(NULL, "%s\n", target_buf);
+ command_print_sameline(NULL, "%s\n", target_buf);
/* NEXT... */
- c -= 16;
- a += 16;
+ bytes -= 16;
+ addr += 16;
}
return JIM_OK;
}
/* found */
break;
}
+
+ /* check for deprecated name */
+ if (target_types[x]->deprecated_name) {
+ if (0 == strcmp(cp, target_types[x]->deprecated_name)) {
+ /* found */
+ LOG_WARNING("target name is deprecated use: \'%s\'", target_types[x]->name);
+ break;
+ }
+ }
}
if (target_types[x] == NULL) {
Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp);
}
/* now - create the new target name command */
- const const struct command_registration target_subcommands[] = {
+ const struct command_registration target_subcommands[] = {
{
.chain = target_instance_command_handlers,
},
},
COMMAND_REGISTRATION_DONE
};
- const const struct command_registration target_commands[] = {
+ const struct command_registration target_commands[] = {
{
.name = cp,
.mode = COMMAND_ANY,
struct command_context *cmd_ctx = current_command_context(interp);
assert(cmd_ctx != NULL);
- Jim_SetResultString(interp, get_current_target(cmd_ctx)->cmd_name, -1);
+ Jim_SetResultString(interp, target_name(get_current_target(cmd_ctx)), -1);
return JIM_OK;
}
target->head = head;
curr = curr->next;
}
- if (target->rtos)
+
+ if (target && target->rtos)
retval = rtos_smp_init(head->target);
+
return retval;
}
.handler = handle_wait_halt_command,
.mode = COMMAND_EXEC,
.help = "wait up to the specified number of milliseconds "
- "(default 5) for a previously requested halt",
+ "(default 5000) for a previously requested halt",
.usage = "[milliseconds]",
},
{
.handler = handle_halt_command,
.mode = COMMAND_EXEC,
.help = "request target to halt, then wait up to the specified"
- "number of milliseconds (default 5) for it to complete",
+ "number of milliseconds (default 5000) for it to complete",
.usage = "[milliseconds]",
},
{