X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=7946f76facbb4806d3548375cb3e28e60e10f37e;hp=693eb519eb13aa1ec4c7f24ad16ad906c4084eaa;hb=79a92d467dae86eefee57ab7170f61cc51d9b0be;hpb=fd8a3c9516d6580ab749e4127f6dab0077a8b078 diff --git a/src/target/target.c b/src/target/target.c index 693eb519eb..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); } @@ -4535,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; @@ -4813,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; @@ -4911,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) { @@ -5346,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) { @@ -5413,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]", }, @@ -5473,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", @@ -5872,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", @@ -6078,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 }; @@ -6413,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]", }, { @@ -6441,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]", }, {