X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=7946f76facbb4806d3548375cb3e28e60e10f37e;hp=7e30d789b62d9e50a0972af2219909ff8ed478fc;hb=79a92d467dae86eefee57ab7170f61cc51d9b0be;hpb=7345801b69d2511252d587159bb9758532797233;ds=sidebyside
diff --git a/src/target/target.c b/src/target/target.c
index 7e30d789b6..7946f76fac 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -251,6 +251,7 @@ static const Jim_Nvp nvp_target_debug_reason[] = {
{ .name = "single-step" , .value = DBG_REASON_SINGLESTEP },
{ .name = "target-not-halted" , .value = DBG_REASON_NOTHALTED },
{ .name = "program-exit" , .value = DBG_REASON_EXIT },
+ { .name = "exception-catch" , .value = DBG_REASON_EXC_CATCH },
{ .name = "undefined" , .value = DBG_REASON_UNDEFINED },
{ .name = NULL, .value = -1 },
};
@@ -375,7 +376,7 @@ uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer)
}
/* read a uint8_t from a buffer in target memory endianness */
-static uint8_t target_buffer_get_u8(struct target *target, const uint8_t *buffer)
+static __attribute__((unused)) uint8_t target_buffer_get_u8(struct target *target, const uint8_t *buffer)
{
return *buffer & 0x0ff;
}
@@ -639,7 +640,7 @@ int target_resume(struct target *target, int current, target_addr_t address,
return retval;
}
-static int target_process_reset(struct command_context *cmd_ctx, enum target_reset_mode reset_mode)
+static int target_process_reset(struct command_invocation *cmd, enum target_reset_mode reset_mode)
{
char buf[100];
int retval;
@@ -663,13 +664,13 @@ static int target_process_reset(struct command_context *cmd_ctx, enum target_res
jtag_poll_set_enabled(false);
sprintf(buf, "ocd_process_reset %s", n->name);
- retval = Jim_Eval(cmd_ctx->interp, buf);
+ retval = Jim_Eval(cmd->ctx->interp, buf);
jtag_poll_set_enabled(save_poll);
if (retval != JIM_OK) {
- Jim_MakeErrorMessage(cmd_ctx->interp);
- command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(cmd_ctx->interp), NULL));
+ Jim_MakeErrorMessage(cmd->ctx->interp);
+ command_print(cmd->ctx, "%s", Jim_GetString(Jim_GetResult(cmd->ctx->interp), NULL));
return ERROR_FAIL;
}
@@ -1256,6 +1257,22 @@ int target_gdb_fileio_end(struct target *target, int retcode, int fileio_errno,
return target->type->gdb_fileio_end(target, retcode, fileio_errno, ctrl_c);
}
+target_addr_t target_address_max(struct target *target)
+{
+ unsigned bits = target_address_bits(target);
+ if (sizeof(target_addr_t) * 8 == bits)
+ return (target_addr_t) -1;
+ else
+ return (((target_addr_t) 1) << bits) - 1;
+}
+
+unsigned target_address_bits(struct target *target)
+{
+ if (target->type->address_bits)
+ return target->type->address_bits(target);
+ return 32;
+}
+
int target_profiling(struct target *target, uint32_t *samples,
uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
{
@@ -1357,7 +1374,7 @@ static int target_init(struct command_context *cmd_ctx)
return retval;
retval = target_register_timer_callback(&handle_target,
- polling_interval, 1, cmd_ctx->interp);
+ polling_interval, TARGET_TIMER_TYPE_PERIODIC, cmd_ctx->interp);
if (ERROR_OK != retval)
return retval;
@@ -1460,7 +1477,8 @@ int target_register_trace_callback(int (*callback)(struct target *target,
return ERROR_OK;
}
-int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int periodic, void *priv)
+int target_register_timer_callback(int (*callback)(void *priv),
+ unsigned int time_ms, enum target_timer_type type, void *priv)
{
struct target_timer_callback **callbacks_p = &target_timer_callbacks;
@@ -1475,7 +1493,7 @@ int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int
(*callbacks_p) = malloc(sizeof(struct target_timer_callback));
(*callbacks_p)->callback = callback;
- (*callbacks_p)->periodic = periodic;
+ (*callbacks_p)->type = type;
(*callbacks_p)->time_ms = time_ms;
(*callbacks_p)->removed = false;
@@ -1625,7 +1643,7 @@ static int target_call_timer_callback(struct target_timer_callback *cb,
{
cb->callback(cb->priv);
- if (cb->periodic)
+ if (cb->type == TARGET_TIMER_TYPE_PERIODIC)
return target_timer_callback_periodic_restart(cb, now);
return target_unregister_timer_callback(cb->callback, cb->priv);
@@ -1659,7 +1677,7 @@ static int target_call_timer_callbacks_check_time(int checktime)
}
bool call_it = (*callback)->callback &&
- ((!checktime && (*callback)->periodic) ||
+ ((!checktime && (*callback)->type == TARGET_TIMER_TYPE_PERIODIC) ||
timeval_compare(&now, &(*callback)->when) >= 0);
if (call_it)
@@ -3061,7 +3079,7 @@ COMMAND_HANDLER(handle_reset_command)
}
/* reset *all* targets */
- return target_process_reset(CMD_CTX, reset_mode);
+ return target_process_reset(CMD, reset_mode);
}
@@ -3719,38 +3737,31 @@ static int handle_bp_command_set(struct command_context *cmd_ctx,
if (asid == 0) {
retval = breakpoint_add(target, addr, length, hw);
+ /* error is always logged in breakpoint_add(), do not print it again */
if (ERROR_OK == retval)
command_print(cmd_ctx, "breakpoint set at " TARGET_ADDR_FMT "", addr);
- else {
- LOG_ERROR("Failure setting breakpoint, the same address(IVA) is already used");
- return retval;
- }
+
} else if (addr == 0) {
if (target->type->add_context_breakpoint == NULL) {
- LOG_WARNING("Context breakpoint not available");
- return ERROR_OK;
+ LOG_ERROR("Context breakpoint not available");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
retval = context_breakpoint_add(target, asid, length, hw);
+ /* error is always logged in context_breakpoint_add(), do not print it again */
if (ERROR_OK == retval)
command_print(cmd_ctx, "Context breakpoint set at 0x%8.8" PRIx32 "", asid);
- else {
- LOG_ERROR("Failure setting breakpoint, the same address(CONTEXTID) is already used");
- return retval;
- }
+
} else {
if (target->type->add_hybrid_breakpoint == NULL) {
- LOG_WARNING("Hybrid breakpoint not available");
- return ERROR_OK;
+ LOG_ERROR("Hybrid breakpoint not available");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
retval = hybrid_breakpoint_add(target, addr, asid, length, hw);
+ /* error is always logged in hybrid_breakpoint_add(), do not print it again */
if (ERROR_OK == retval)
command_print(cmd_ctx, "Hybrid breakpoint set at 0x%8.8" PRIx32 "", asid);
- else {
- LOG_ERROR("Failure setting breakpoint, the same address is already used");
- return retval;
- }
}
- return ERROR_OK;
+ return retval;
}
COMMAND_HANDLER(handle_bp_command)
@@ -4542,7 +4553,12 @@ void target_handle_event(struct target *target, enum target_event e)
if (Jim_EvalObj(teap->interp, teap->body) != JIM_OK) {
Jim_MakeErrorMessage(teap->interp);
- command_print(NULL, "%s\n", Jim_GetString(Jim_GetResult(teap->interp), NULL));
+ LOG_USER("Error executing event %s on target %s:\n%s",
+ Jim_Nvp_value2name_simple(nvp_target_event, e)->name,
+ target_name(target),
+ Jim_GetString(Jim_GetResult(teap->interp), NULL));
+ /* clean both error code and stacktrace before return */
+ Jim_Eval(teap->interp, "error \"\" \"\"");
}
cmd_ctx->current_target_override = saved_target_override;
@@ -4820,7 +4836,7 @@ no_params:
if (goi->argc != 0)
goto no_params;
}
- Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->coreid));
/* loop for more */
break;
@@ -4918,228 +4934,6 @@ static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *a
return target_configure(&goi, target);
}
-static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- const char *cmd_name = Jim_GetString(argv[0], NULL);
-
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
-
- if (goi.argc < 2 || goi.argc > 4) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s [phys]
[]", cmd_name);
- return JIM_ERR;
- }
-
- target_write_fn fn;
- fn = target_write_memory;
-
- int e;
- if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) {
- /* consume it */
- struct Jim_Obj *obj;
- e = Jim_GetOpt_Obj(&goi, &obj);
- if (e != JIM_OK)
- return e;
-
- fn = target_write_phys_memory;
- }
-
- jim_wide a;
- e = Jim_GetOpt_Wide(&goi, &a);
- if (e != JIM_OK)
- return e;
-
- jim_wide b;
- e = Jim_GetOpt_Wide(&goi, &b);
- if (e != JIM_OK)
- return e;
-
- jim_wide c = 1;
- if (goi.argc == 1) {
- e = Jim_GetOpt_Wide(&goi, &c);
- if (e != JIM_OK)
- return e;
- }
-
- /* all args must be consumed */
- if (goi.argc != 0)
- return JIM_ERR;
-
- struct target *target = Jim_CmdPrivData(goi.interp);
- unsigned data_size;
- if (strcasecmp(cmd_name, "mww") == 0)
- data_size = 4;
- else if (strcasecmp(cmd_name, "mwh") == 0)
- data_size = 2;
- else if (strcasecmp(cmd_name, "mwb") == 0)
- data_size = 1;
- else {
- LOG_ERROR("command '%s' unknown: ", cmd_name);
- return JIM_ERR;
- }
-
- 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] [] - for 32 bit reads
-* mdh [phys] [] - for 16 bit reads
-* mdb [phys] [] - 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 [] 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);
-
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
-
- if ((goi.argc < 1) || (goi.argc > 3)) {
- Jim_SetResultFormatted(goi.interp,
- "usage: %s [phys] []", cmd_name);
- return JIM_ERR;
- }
-
- int (*fn)(struct target *target,
- target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);
- fn = target_read_memory;
-
- int e;
- if (strcmp(Jim_GetString(argv[1], NULL), "phys") == 0) {
- /* consume it */
- struct Jim_Obj *obj;
- e = Jim_GetOpt_Obj(&goi, &obj);
- if (e != JIM_OK)
- return e;
-
- fn = target_read_phys_memory;
- }
-
- /* Read address parameter */
- jim_wide addr;
- e = Jim_GetOpt_Wide(&goi, &addr);
- if (e != JIM_OK)
- return JIM_ERR;
-
- /* 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, &count);
- if (e != JIM_OK)
- return JIM_ERR;
- } else
- count = 1;
-
- /* all args must be consumed */
- if (goi.argc != 0)
- return JIM_ERR;
-
- jim_wide dwidth = 1; /* shut up gcc */
- if (strcasecmp(cmd_name, "mdw") == 0)
- dwidth = 4;
- else if (strcasecmp(cmd_name, "mdh") == 0)
- dwidth = 2;
- else if (strcasecmp(cmd_name, "mdb") == 0)
- dwidth = 1;
- else {
- LOG_ERROR("command '%s' unknown: ", cmd_name);
- return JIM_ERR;
- }
-
- /* convert count to "bytes" */
- int bytes = count * dwidth;
-
- struct target *target = Jim_CmdPrivData(goi.interp);
- uint8_t target_buf[32];
- jim_wide x, y, z;
- 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) {
- Jim_SetResultFormatted(interp, "error reading target @ 0x%08lx", (long)addr);
- return JIM_ERR;
- }
-
- 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_sameline(NULL, "%08x ", (int)(z));
- }
- for (; (x < 16) ; x += 4)
- 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_sameline(NULL, "%04x ", (int)(z));
- }
- for (; (x < 16) ; x += 2)
- 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_sameline(NULL, "%02x ", (int)(z));
- }
- for (; (x < 16) ; x += 1)
- command_print_sameline(NULL, " ");
- break;
- }
- /* ascii-ify the bytes */
- for (x = 0 ; x < y ; x++) {
- if ((target_buf[x] >= 0x20) &&
- (target_buf[x] <= 0x7e)) {
- /* good */
- } else {
- /* smack it */
- target_buf[x] = '.';
- }
- }
- /* space pad */
- while (x < 16) {
- target_buf[x] = ' ';
- x++;
- }
- /* terminate */
- target_buf[16] = 0;
- /* print - with a newline */
- command_print_sameline(NULL, "%s\n", target_buf);
- /* NEXT... */
- bytes -= 16;
- addr += 16;
- }
- return JIM_OK;
-}
-
static int jim_target_mem2array(Jim_Interp *interp,
int argc, Jim_Obj *const *argv)
{
@@ -5353,27 +5147,25 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a
/* List for human, Events defined for this target.
* scripts/programs should use 'name cget -event NAME'
*/
-static int jim_target_event_list(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+COMMAND_HANDLER(handle_target_event_list)
{
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx != NULL);
-
- struct target *target = Jim_CmdPrivData(interp);
+ struct target *target = get_current_target(CMD_CTX);
struct target_event_action *teap = target->event_action;
- command_print(cmd_ctx, "Event actions for target (%d) %s\n",
+
+ command_print(CMD_CTX, "Event actions for target (%d) %s\n",
target->target_number,
target_name(target));
- command_print(cmd_ctx, "%-25s | Body", "Event");
- command_print(cmd_ctx, "------------------------- | "
+ command_print(CMD_CTX, "%-25s | Body", "Event");
+ command_print(CMD_CTX, "------------------------- | "
"----------------------------------------");
while (teap) {
Jim_Nvp *opt = Jim_Nvp_value2name_simple(nvp_target_event, teap->event);
- command_print(cmd_ctx, "%-25s | %s",
+ command_print(CMD_CTX, "%-25s | %s",
opt->name, Jim_GetString(teap->body, NULL));
teap = teap->next;
}
- command_print(cmd_ctx, "***END***");
- return JIM_OK;
+ command_print(CMD_CTX, "***END***");
+ return ERROR_OK;
}
static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
@@ -5420,45 +5212,59 @@ static const struct command_registration target_instance_command_handlers[] = {
.help = "returns the specified target attribute",
.usage = "target_attribute",
},
+ {
+ .name = "mwd",
+ .handler = handle_mw_command,
+ .mode = COMMAND_EXEC,
+ .help = "Write 64-bit word(s) to target memory",
+ .usage = "address data [count]",
+ },
{
.name = "mww",
+ .handler = handle_mw_command,
.mode = COMMAND_EXEC,
- .jim_handler = jim_target_mw,
.help = "Write 32-bit word(s) to target memory",
.usage = "address data [count]",
},
{
.name = "mwh",
+ .handler = handle_mw_command,
.mode = COMMAND_EXEC,
- .jim_handler = jim_target_mw,
.help = "Write 16-bit half-word(s) to target memory",
.usage = "address data [count]",
},
{
.name = "mwb",
+ .handler = handle_mw_command,
.mode = COMMAND_EXEC,
- .jim_handler = jim_target_mw,
.help = "Write byte(s) to target memory",
.usage = "address data [count]",
},
+ {
+ .name = "mdd",
+ .handler = handle_md_command,
+ .mode = COMMAND_EXEC,
+ .help = "Display target memory as 64-bit words",
+ .usage = "address [count]",
+ },
{
.name = "mdw",
+ .handler = handle_md_command,
.mode = COMMAND_EXEC,
- .jim_handler = jim_target_md,
.help = "Display target memory as 32-bit words",
.usage = "address [count]",
},
{
.name = "mdh",
+ .handler = handle_md_command,
.mode = COMMAND_EXEC,
- .jim_handler = jim_target_md,
.help = "Display target memory as 16-bit half-words",
.usage = "address [count]",
},
{
.name = "mdb",
+ .handler = handle_md_command,
.mode = COMMAND_EXEC,
- .jim_handler = jim_target_md,
.help = "Display target memory as 8-bit bytes",
.usage = "address [count]",
},
@@ -5480,9 +5286,10 @@ static const struct command_registration target_instance_command_handlers[] = {
},
{
.name = "eventlist",
+ .handler = handle_target_event_list,
.mode = COMMAND_EXEC,
- .jim_handler = jim_target_event_list,
.help = "displays a table of events defined for this target",
+ .usage = "",
},
{
.name = "curstate",
@@ -5879,6 +5686,7 @@ static const struct command_registration target_subcommand_handlers[] = {
.mode = COMMAND_CONFIG,
.handler = handle_target_init_command,
.help = "initialize targets",
+ .usage = "",
},
{
.name = "create",
@@ -6085,8 +5893,8 @@ static const struct command_registration target_command_handlers[] = {
.name = "target",
.mode = COMMAND_CONFIG,
.help = "configure target",
-
.chain = target_subcommand_handlers,
+ .usage = "",
},
COMMAND_REGISTRATION_DONE
};
@@ -6420,7 +6228,7 @@ static const struct command_registration target_exec_command_handlers[] = {
.name = "mdd",
.handler = handle_md_command,
.mode = COMMAND_EXEC,
- .help = "display memory words",
+ .help = "display memory double-words",
.usage = "['phys'] address [count]",
},
{
@@ -6448,7 +6256,7 @@ static const struct command_registration target_exec_command_handlers[] = {
.name = "mwd",
.handler = handle_mw_command,
.mode = COMMAND_EXEC,
- .help = "write memory word",
+ .help = "write memory double-word",
.usage = "['phys'] address value [count]",
},
{