X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=ab094f96775b5441e0b8374f60017b44584931f8;hp=d4cb577c4dab5a11e863e941c21cd7864b6b696c;hb=61f3d4b7e42897fb1570bd4307137833cce0f7ba;hpb=c9f51acdc31a6277b9a743974fed06d390df221e diff --git a/src/target/target.c b/src/target/target.c index d4cb577c4d..ab094f9677 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -84,6 +84,7 @@ extern struct target_type dsp563xx_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; static struct target_type *target_types[] = { @@ -107,6 +108,7 @@ static struct target_type *target_types[] = &dsp5680xx_target, &testee_target, &avr32_ap7k_target, + &stm32_stlink_target, NULL, }; @@ -940,6 +942,8 @@ static int target_init_one(struct command_context *cmd_ctx, if (type->check_reset== NULL) type->check_reset = default_check_reset; + assert(type->init_target != NULL); + int retval = type->init_target(cmd_ctx, target); if (ERROR_OK != retval) { @@ -1043,6 +1047,8 @@ static int target_init(struct command_context *cmd_ctx) COMMAND_HANDLER(handle_target_init_command) { + int retval; + if (CMD_ARGC != 0) return ERROR_COMMAND_SYNTAX_ERROR; @@ -1054,6 +1060,10 @@ COMMAND_HANDLER(handle_target_init_command) } target_initialized = true; + retval = command_run_line(CMD_CTX, "init_targets"); + if (ERROR_OK != retval) + return retval; + LOG_DEBUG("Initializing targets..."); return target_init(CMD_CTX); } @@ -1064,7 +1074,7 @@ int target_register_event_callback(int (*callback)(struct target *target, enum t if (callback == NULL) { - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; } if (*callbacks_p) @@ -1089,7 +1099,7 @@ int target_register_timer_callback(int (*callback)(void *priv), int time_ms, int if (callback == NULL) { - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; } if (*callbacks_p) @@ -1127,7 +1137,7 @@ int target_unregister_event_callback(int (*callback)(struct target *target, enum if (callback == NULL) { - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; } while (c) @@ -1154,7 +1164,7 @@ static int target_unregister_timer_callback(int (*callback)(void *priv), void *p if (callback == NULL) { - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; } while (c) @@ -1671,7 +1681,7 @@ int target_checksum_memory(struct target *target, uint32_t address, uint32_t siz if (buffer == NULL) { LOG_ERROR("error allocating buffer for section (%d bytes)", (int)size); - return ERROR_INVALID_ARGUMENTS; + return ERROR_COMMAND_SYNTAX_ERROR; } retval = target_read_buffer(target, address, size, buffer); if (retval != ERROR_OK) @@ -1861,30 +1871,38 @@ int target_write_u8(struct target *target, uint32_t address, uint8_t value) return retval; } -COMMAND_HANDLER(handle_targets_command) +static int find_target(struct command_context *cmd_ctx, const char *name) { - struct target *target = all_targets; + struct target *target = get_target(name); + if (target == NULL) { + LOG_ERROR("Target: %s is unknown, try one of:\n", name); + return ERROR_FAIL; + } + if (!target->tap->enabled) { + LOG_USER("Target: TAP %s is disabled, " + "can't be the current target\n", + target->tap->dotted_name); + return ERROR_FAIL; + } + + cmd_ctx->current_target = target->target_number; + return ERROR_OK; +} + +COMMAND_HANDLER(handle_targets_command) +{ + int retval = ERROR_OK; if (CMD_ARGC == 1) { - target = get_target(CMD_ARGV[0]); - if (target == NULL) { - command_print(CMD_CTX,"Target: %s is unknown, try one of:\n", CMD_ARGV[0]); - goto DumpTargets; - } - if (!target->tap->enabled) { - command_print(CMD_CTX,"Target: TAP %s is disabled, " - "can't be the current target\n", - target->tap->dotted_name); - return ERROR_FAIL; + retval = find_target(CMD_CTX, CMD_ARGV[0]); + if (retval == ERROR_OK) { + /* we're done! */ + return retval; } - - CMD_CTX->current_target = target->target_number; - return ERROR_OK; } -DumpTargets: - target = all_targets; + struct target *target = all_targets; command_print(CMD_CTX, " TargetName Type Endian TapName State "); command_print(CMD_CTX, "-- ------------------ ---------- ------ ------------------ ------------"); while (target) @@ -1901,19 +1919,20 @@ DumpTargets: marker = '*'; /* keep columns lined up to match the headers above */ - command_print(CMD_CTX, "%2d%c %-18s %-10s %-6s %-18s %s", - target->target_number, - marker, - target_name(target), - target_type_name(target), - Jim_Nvp_value2name_simple(nvp_target_endian, - target->endianness)->name, - target->tap->dotted_name, - state); + command_print(CMD_CTX, + "%2d%c %-18s %-10s %-6s %-18s %s", + target->target_number, + marker, + target_name(target), + target_type_name(target), + Jim_Nvp_value2name_simple(nvp_target_endian, + target->endianness)->name, + target->tap->dotted_name, + state); target = target->next; } - return ERROR_OK; + return retval; } /* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */ @@ -2190,6 +2209,8 @@ COMMAND_HANDLER(handle_reg_command) } } + assert(reg != NULL); /* give clang a hint that we *know* reg is != NULL here */ + /* display a register */ if ((CMD_ARGC == 1) || ((CMD_ARGC == 2) && !((CMD_ARGV[1][0] >= '0') && (CMD_ARGV[1][0] <= '9')))) { @@ -2210,6 +2231,8 @@ COMMAND_HANDLER(handle_reg_command) if (CMD_ARGC == 2) { uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8)); + if (buf == NULL) + return ERROR_FAIL; str_to_buf(CMD_ARGV[1], strlen(CMD_ARGV[1]), buf, reg->size, 0); reg->type->set(reg, buf); @@ -2223,9 +2246,7 @@ COMMAND_HANDLER(handle_reg_command) return ERROR_OK; } - command_print(CMD_CTX, "usage: reg <#|name> [value]"); - - return ERROR_OK; + return ERROR_COMMAND_SYNTAX_ERROR; } COMMAND_HANDLER(handle_poll_command) @@ -2272,7 +2293,6 @@ COMMAND_HANDLER(handle_wait_halt_command) int retval = parse_uint(CMD_ARGV[0], &ms); if (ERROR_OK != retval) { - command_print(CMD_CTX, "usage: %s [seconds]", CMD_NAME); return ERROR_COMMAND_SYNTAX_ERROR; } // convert seconds (given) to milliseconds (needed) @@ -2777,7 +2797,7 @@ COMMAND_HANDLER(handle_load_image_command) COMMAND_HANDLER(handle_dump_image_command) { struct fileio fileio; - uint8_t buffer[560]; + uint8_t *buffer; int retval, retvaltemp; uint32_t address, size; struct duration bench; @@ -2789,17 +2809,23 @@ COMMAND_HANDLER(handle_dump_image_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], address); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], size); + uint32_t buf_size = (size > 4096) ? 4096 : size; + buffer = malloc(buf_size); + if (!buffer) + return ERROR_FAIL; + retval = fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY); - if (retval != ERROR_OK) + if (retval != ERROR_OK) { + free(buffer); return retval; + } duration_start(&bench); - retval = ERROR_OK; while (size > 0) { size_t size_written; - uint32_t this_run_size = (size > 560) ? 560 : size; + uint32_t this_run_size = (size > buf_size) ? buf_size : size; retval = target_read_buffer(target, address, this_run_size, buffer); if (retval != ERROR_OK) { @@ -2816,6 +2842,8 @@ COMMAND_HANDLER(handle_dump_image_command) address += this_run_size; } + free(buffer); + if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) { int filesize; @@ -3132,7 +3160,6 @@ COMMAND_HANDLER(handle_bp_command) return handle_bp_command_set(CMD_CTX, addr, asid, length, hw); default: - command_print(CMD_CTX, "usage: bp
[] ['hw'|'hw_ctx']"); return ERROR_COMMAND_SYNTAX_ERROR; } } @@ -3212,8 +3239,6 @@ COMMAND_HANDLER(handle_wp_command) break; default: - command_print(CMD_CTX, "usage: wp [address length " - "[(r|w|a) [value [mask]]]]"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -3414,9 +3439,9 @@ COMMAND_HANDLER(handle_profile_command) /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */ struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1); + int retval = ERROR_OK; for (;;) { - int retval; target_poll(target); if (target->state == TARGET_HALTED) { @@ -3469,7 +3494,7 @@ COMMAND_HANDLER(handle_profile_command) } free(samples); - return ERROR_OK; + return retval; } static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, uint32_t val) @@ -3634,7 +3659,7 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL); e = JIM_ERR; - len = 0; + break; } else { v = 0; /* shut up gcc */ for (i = 0 ;i < count ;i++, n++) { @@ -3659,7 +3684,7 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - return JIM_OK; + return e; } static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, uint32_t *val) @@ -3844,7 +3869,7 @@ static int target_array2mem(Jim_Interp *interp, struct target *target, Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: cannot read memory", NULL); e = JIM_ERR; - len = 0; + break; } } @@ -3852,7 +3877,7 @@ static int target_array2mem(Jim_Interp *interp, struct target *target, Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); - return JIM_OK; + return e; } /* FIX? should we propagate errors here rather than printing them @@ -4164,6 +4189,8 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) free((void *)(target->variant)); } e = Jim_GetOpt_String(goi, &cp, NULL); + if (e != JIM_OK) + return e; target->variant = strdup(cp); } else { if (goi->argc != 0) { @@ -4889,6 +4916,8 @@ static int target_create(Jim_GetOptInfo *goi) /* TYPE */ e = Jim_GetOpt_String(goi, &cp2, NULL); + if (e != JIM_OK) + return e; cp = cp2; /* now does target type exist */ for (x = 0 ; target_types[x] ; x++) { @@ -5029,6 +5058,7 @@ static int target_create(Jim_GetOptInfo *goi) .name = cp, .mode = COMMAND_ANY, .help = "target command group", + .usage = "", .chain = target_subcommands, }, COMMAND_REGISTRATION_DONE @@ -5097,11 +5127,11 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) int i; const char *targetname; int retval,len; - struct target *target; + struct target *target = (struct target *) NULL; struct target_list *head, *curr, *new; - curr = (struct target_list*) NULL; - head = (struct target_list*) NULL; - new = (struct target_list*) NULL; + curr = (struct target_list *) NULL; + head = (struct target_list *) NULL; + new = (struct target_list *) NULL; retval = 0; LOG_DEBUG("%d",argc); @@ -5138,11 +5168,13 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) while(curr!=(struct target_list *)NULL) { - target=curr->target; - target->smp = 1; - target->head = head; - curr=curr->next; + target = curr->target; + target->smp = 1; + target->head = head; + curr = curr->next; } + if (target->rtos) + retval = rtos_smp_init(head->target); return retval; } @@ -5491,6 +5523,27 @@ COMMAND_HANDLER(handle_target_reset_nag) "performance"); } +COMMAND_HANDLER(handle_ps_command) +{ + struct target *target = get_current_target(CMD_CTX); + char *display; + if (target->state != TARGET_HALTED) { + LOG_INFO("target not halted !!"); + return ERROR_OK; + } + + if ((target->rtos) && (target->rtos->type) + && (target->rtos->type->ps_command)) { + display = target->rtos->type->ps_command(target); + command_print(CMD_CTX, "%s", display); + free(display); + return ERROR_OK; + } else { + LOG_INFO("failed"); + return ERROR_TARGET_FAILURE; + } +} + static const struct command_registration target_exec_command_handlers[] = { { .name = "fast_load_image", @@ -5507,11 +5560,13 @@ static const struct command_registration target_exec_command_handlers[] = { .mode = COMMAND_EXEC, .help = "loads active fast load image to current target " "- mainly for profiling purposes", + .usage = "", }, { .name = "profile", .handler = handle_profile_command, .mode = COMMAND_EXEC, + .usage = "seconds filename", .help = "profiling samples the CPU PC", }, /** @todo don't register virt2phys() unless target supports it */ @@ -5572,6 +5627,7 @@ static const struct command_registration target_exec_command_handlers[] = { .name = "soft_reset_halt", .handler = handle_soft_reset_halt_command, .mode = COMMAND_EXEC, + .usage = "", .help = "halt the target and do a soft reset", }, { @@ -5628,7 +5684,7 @@ static const struct command_registration target_exec_command_handlers[] = { .handler = handle_bp_command, .mode = COMMAND_EXEC, .help = "list or set hardware or software breakpoint", - .usage = "usage: bp
[] ['hw'|'hw_ctx']", + .usage = "
[] ['hw'|'hw_ctx']", }, { .name = "rbp", @@ -5700,6 +5756,14 @@ static const struct command_registration target_exec_command_handlers[] = { "enabled to improve performance. ", .usage = "['enable'|'disable']", }, + { + .name = "ps", + .handler = handle_ps_command, + .mode = COMMAND_EXEC, + .help = "list all tasks ", + .usage = " ", + }, + COMMAND_REGISTRATION_DONE }; static int target_register_user_commands(struct command_context *cmd_ctx)