From faeae51d7f497d83ab166329abb1f06aa5903774 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Wed, 15 Mar 2023 01:22:10 +0300 Subject: [PATCH 01/50] target/espressif: check common_magic instead of gdb_arch string The value returned by target_get_gdb_arch() is something specific for GDB. There could be several variants of the same CPU. If we start implementing all the variants, checking the string value, could become incorrect. It's better to check for xtensa->common_magic == XTENSA_COMMON_MAGIC Signed-off-by: Erhan Kurubas Change-Id: I20f3fdced176c3b9ab00f889743161ecad7280f9 Reviewed-on: https://review.openocd.org/c/openocd/+/7536 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/espressif/esp_semihosting.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/target/espressif/esp_semihosting.c b/src/target/espressif/esp_semihosting.c index 5e9cb94573..51d499866d 100644 --- a/src/target/espressif/esp_semihosting.c +++ b/src/target/espressif/esp_semihosting.c @@ -17,12 +17,10 @@ static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target) { - const char *arch = target_get_gdb_arch(target); - if (arch) { - if (strncmp(arch, "xtensa", 6) == 0) - return &target_to_esp_xtensa(target)->semihost; - /* TODO: add riscv */ - } + struct xtensa *xtensa = target->arch_info; + if (xtensa->common_magic == XTENSA_COMMON_MAGIC) + return &target_to_esp_xtensa(target)->semihost; + /* TODO: add riscv */ LOG_ERROR("Unknown target arch!"); return NULL; } From 6ecd99ff9b98778d5655d6b6fc245dd8f344d365 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 14 Mar 2023 19:43:21 +0100 Subject: [PATCH 02/50] target/adi_v5_swd: update comment about SWD capability The multidrop SWD is also supported. Change-Id: I9fefc54fc9d40a75194285cd6e0f10c5c347d9b6 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/7537 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/adi_v5_swd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index aea730d4d1..653f91f130 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -13,7 +13,7 @@ * is a transport level interface, with "target/arm_adi_v5.[hc]" code * understanding operation semantics, shared with the JTAG transport. * - * Single-DAP support only. + * Single DAP and multidrop-SWD support. * * for details, see "ARM IHI 0031A" * ARM Debug Interface v5 Architecture Specification From 415715d91a11ea4ed6db3a1fd760741a22b6e098 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 14 Mar 2023 15:11:14 +0100 Subject: [PATCH 03/50] target/adi_v5_jtag: fix endianness error in transaction replay The code for JTAG WAIT recovery did not handle DP_SELECT endianness. While on it, mark missing ADIv6 DP SELECT1 handling as TODO. Change-Id: I44f3bc8fc9fd2483c0293b6d4f2c51a60ca01873 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/7540 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/adi_v5_jtag.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c index eeb796be45..9f66adc688 100644 --- a/src/target/adi_v5_jtag.c +++ b/src/target/adi_v5_jtag.c @@ -566,14 +566,20 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) /* restore SELECT register first */ if (!list_empty(&replay_list)) { el = list_first_entry(&replay_list, struct dap_cmd, lh); + + uint8_t out_value_buf[4]; + buf_set_u32(out_value_buf, 0, 32, (uint32_t)(el->dp_select)); + tmp = dap_cmd_new(dap, JTAG_DP_DPACC, - DP_SELECT, DPAP_WRITE, (uint8_t *)&el->dp_select, NULL, 0); + DP_SELECT, DPAP_WRITE, out_value_buf, NULL, 0); if (!tmp) { retval = ERROR_JTAG_DEVICE_ERROR; goto done; } list_add(&tmp->lh, &replay_list); + /* TODO: ADIv6 DP SELECT1 handling */ + dap->select = DP_SELECT_INVALID; } From 86827a961a22815ebd5fa367468ca7444f0ee2e1 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Mar 2023 11:50:08 +0100 Subject: [PATCH 04/50] svf: fix leaking file descriptor The file descriptor svf_fd is not closed on command error, thus leaking memory. Close svf_fd on errors. While there, properly initialize svf_fd using NULL instead of 0. Change-Id: I5efe9ce576a3a50588b30000222665e26161dfdc Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7532 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: --- src/svf/svf.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/svf/svf.c b/src/svf/svf.c index 7195880670..05fb21d631 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -377,6 +377,9 @@ COMMAND_HANDLER(handle_svf_command) svf_addcycles = atoi(CMD_ARGV[i + 1]); if (svf_addcycles > SVF_MAX_ADDCYCLES) { command_print(CMD, "addcycles: %s out of range", CMD_ARGV[i + 1]); + if (svf_fd) + fclose(svf_fd); + svf_fd = NULL; return ERROR_FAIL; } i++; @@ -384,6 +387,9 @@ COMMAND_HANDLER(handle_svf_command) tap = jtag_tap_by_string(CMD_ARGV[i+1]); if (!tap) { command_print(CMD, "Tap: %s unknown", CMD_ARGV[i+1]); + if (svf_fd) + fclose(svf_fd); + svf_fd = NULL; return ERROR_FAIL; } i++; @@ -546,7 +552,7 @@ COMMAND_HANDLER(handle_svf_command) free_all: fclose(svf_fd); - svf_fd = 0; + svf_fd = NULL; /* free buffers */ free(svf_command_buffer); From f8631c3650c0e3a3c3e16726f1ca3748d163cc69 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Mar 2023 12:01:03 +0100 Subject: [PATCH 05/50] svf: fix memory leak on error during command execution If svf_set_padding() returns error, jump to free_all label to prevent any memory leak. Propagate the error reported by svf_set_padding() instead of overwriting it. Use command_print() instead of LOG_ERROR() for command output. Change-Id: I61fd89cad10652f2f9ef1f9d48a040e35253c3d4 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7533 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/svf/svf.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/svf/svf.c b/src/svf/svf.c index 05fb21d631..2a13312804 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -473,27 +473,31 @@ COMMAND_HANDLER(handle_svf_command) } /* HDR %d TDI (0) */ - if (svf_set_padding(&svf_para.hdr_para, header_dr_len, 0) != ERROR_OK) { - LOG_ERROR("failed to set data header"); - return ERROR_FAIL; + ret = svf_set_padding(&svf_para.hdr_para, header_dr_len, 0); + if (ret != ERROR_OK) { + command_print(CMD, "failed to set data header"); + goto free_all; } /* HIR %d TDI (0xFF) */ - if (svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF) != ERROR_OK) { - LOG_ERROR("failed to set instruction header"); - return ERROR_FAIL; + ret = svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF); + if (ret != ERROR_OK) { + command_print(CMD, "failed to set instruction header"); + goto free_all; } /* TDR %d TDI (0) */ - if (svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0) != ERROR_OK) { - LOG_ERROR("failed to set data trailer"); - return ERROR_FAIL; + ret = svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0); + if (ret != ERROR_OK) { + command_print(CMD, "failed to set data trailer"); + goto free_all; } /* TIR %d TDI (0xFF) */ - if (svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF) != ERROR_OK) { - LOG_ERROR("failed to set instruction trailer"); - return ERROR_FAIL; + ret = svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF); + if (ret != ERROR_OK) { + command_print(CMD, "failed to set instruction trailer"); + goto free_all; } } From 5f6ceebbba3a34fc4bfcf56e963739dd2e9cf056 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 10 Mar 2023 11:41:54 +0100 Subject: [PATCH 06/50] svf: make command 'svf' syntax consistent The command 'svf' is the only command in OpenOCD that accepts options in both forms 'option' and '-option'. Deprecate the option format without the leading '-'. Update the documentation and fix the on-line help. While there: - switch to use the new nvp.h helper; - return ERROR_COMMAND_ARGUMENT_INVALID on invalid command args; - fix some minor coding style rule. Change-Id: I5b944403d92a3fa1e12d5faafc1d2a139bc16a7d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7534 Tested-by: jenkins --- doc/openocd.texi | 12 +++--- src/svf/svf.c | 95 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 83 insertions(+), 24 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 0de101b6da..26a59e6a72 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -11432,8 +11432,8 @@ way to represent JTAG test patterns in text files. In a debug session using JTAG for its transport protocol, OpenOCD supports running such test files. -@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{[-]quiet}] @ - [@option{[-]nil}] [@option{[-]progress}] [@option{[-]ignore_error}] @ +@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{-quiet}] @ + [@option{-nil}] [@option{-progress}] [@option{-ignore_error}] @ [@option{-noreset}] [@option{-addcycles @var{cyclecount}}] This issues a JTAG reset (Test-Logic-Reset) and then runs the SVF script from @file{filename}. @@ -11447,11 +11447,11 @@ Command options: specified by the SVF file with HIR, TIR, HDR and TDR commands; instead, calculate them automatically according to the current JTAG chain configuration, targeting @var{tapname}; -@item @option{[-]quiet} do not log every command before execution; -@item @option{[-]nil} ``dry run'', i.e., do not perform any operations +@item @option{-quiet} do not log every command before execution; +@item @option{-nil} ``dry run'', i.e., do not perform any operations on the real interface; -@item @option{[-]progress} enable progress indication; -@item @option{[-]ignore_error} continue execution despite TDO check +@item @option{-progress} enable progress indication; +@item @option{-ignore_error} continue execution despite TDO check errors. @item @option{-noreset} omit JTAG reset (Test-Logic-Reset) before executing content of the SVF file; diff --git a/src/svf/svf.c b/src/svf/svf.c index 2a13312804..dd3d5175c3 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -22,6 +22,7 @@ #include "svf.h" #include "helper/system.h" #include +#include #include /* SVF command */ @@ -346,6 +347,37 @@ int svf_add_statemove(tap_state_t state_to) return ERROR_FAIL; } +enum svf_cmd_param { + OPT_ADDCYCLES, + OPT_IGNORE_ERROR, + OPT_NIL, + OPT_NORESET, + OPT_PROGRESS, + OPT_QUIET, + OPT_TAP, + /* DEPRECATED */ + DEPRECATED_OPT_IGNORE_ERROR, + DEPRECATED_OPT_NIL, + DEPRECATED_OPT_PROGRESS, + DEPRECATED_OPT_QUIET, +}; + +static const struct nvp svf_cmd_opts[] = { + { .name = "-addcycles", .value = OPT_ADDCYCLES }, + { .name = "-ignore_error", .value = OPT_IGNORE_ERROR }, + { .name = "-nil", .value = OPT_NIL }, + { .name = "-noreset", .value = OPT_NORESET }, + { .name = "-progress", .value = OPT_PROGRESS }, + { .name = "-quiet", .value = OPT_QUIET }, + { .name = "-tap", .value = OPT_TAP }, + /* DEPRECATED */ + { .name = "ignore_error", .value = DEPRECATED_OPT_IGNORE_ERROR }, + { .name = "nil", .value = DEPRECATED_OPT_NIL }, + { .name = "progress", .value = DEPRECATED_OPT_PROGRESS }, + { .name = "quiet", .value = DEPRECATED_OPT_QUIET }, + { .name = NULL, .value = -1 } +}; + COMMAND_HANDLER(handle_svf_command) { #define SVF_MIN_NUM_OF_OPTIONS 1 @@ -355,10 +387,11 @@ COMMAND_HANDLER(handle_svf_command) int64_t time_measure_ms; int time_measure_s, time_measure_m; - /* use NULL to indicate a "plain" svf file which accounts for + /* + * use NULL to indicate a "plain" svf file which accounts for * any additional devices in the scan chain, otherwise the device * that should be affected - */ + */ struct jtag_tap *tap = NULL; if ((CMD_ARGC < SVF_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > SVF_MAX_NUM_OF_OPTIONS)) @@ -373,48 +406,74 @@ COMMAND_HANDLER(handle_svf_command) svf_addcycles = 0; for (unsigned int i = 0; i < CMD_ARGC; i++) { - if (strcmp(CMD_ARGV[i], "-addcycles") == 0) { + const struct nvp *n = nvp_name2value(svf_cmd_opts, CMD_ARGV[i]); + switch (n->value) { + case OPT_ADDCYCLES: svf_addcycles = atoi(CMD_ARGV[i + 1]); if (svf_addcycles > SVF_MAX_ADDCYCLES) { command_print(CMD, "addcycles: %s out of range", CMD_ARGV[i + 1]); if (svf_fd) fclose(svf_fd); svf_fd = NULL; - return ERROR_FAIL; + return ERROR_COMMAND_ARGUMENT_INVALID; } i++; - } else if (strcmp(CMD_ARGV[i], "-tap") == 0) { + break; + + case OPT_TAP: tap = jtag_tap_by_string(CMD_ARGV[i+1]); if (!tap) { command_print(CMD, "Tap: %s unknown", CMD_ARGV[i+1]); if (svf_fd) fclose(svf_fd); svf_fd = NULL; - return ERROR_FAIL; + return ERROR_COMMAND_ARGUMENT_INVALID; } i++; - } else if ((strcmp(CMD_ARGV[i], - "quiet") == 0) || (strcmp(CMD_ARGV[i], "-quiet") == 0)) + break; + + case DEPRECATED_OPT_QUIET: + LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); + /* fallthrough */ + case OPT_QUIET: svf_quiet = 1; - else if ((strcmp(CMD_ARGV[i], "nil") == 0) || (strcmp(CMD_ARGV[i], "-nil") == 0)) + break; + + case DEPRECATED_OPT_NIL: + LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); + /* fallthrough */ + case OPT_NIL: svf_nil = 1; - else if ((strcmp(CMD_ARGV[i], - "progress") == 0) || (strcmp(CMD_ARGV[i], "-progress") == 0)) + break; + + case DEPRECATED_OPT_PROGRESS: + LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); + /* fallthrough */ + case OPT_PROGRESS: svf_progress_enabled = 1; - else if ((strcmp(CMD_ARGV[i], - "ignore_error") == 0) || (strcmp(CMD_ARGV[i], "-ignore_error") == 0)) + break; + + case DEPRECATED_OPT_IGNORE_ERROR: + LOG_INFO("DEPRECATED flag '%s'; use '-%s'", CMD_ARGV[i], CMD_ARGV[i]); + /* fallthrough */ + case OPT_IGNORE_ERROR: svf_ignore_error = 1; - else if (strcmp(CMD_ARGV[i], "-noreset") == 0) + break; + + case OPT_NORESET: svf_noreset = true; - else { + break; + + default: svf_fd = fopen(CMD_ARGV[i], "r"); if (!svf_fd) { int err = errno; command_print(CMD, "open(\"%s\"): %s", CMD_ARGV[i], strerror(err)); /* no need to free anything now */ return ERROR_COMMAND_SYNTAX_ERROR; - } else - LOG_USER("svf processing file: \"%s\"", CMD_ARGV[i]); + } + LOG_USER("svf processing file: \"%s\"", CMD_ARGV[i]); + break; } } @@ -1576,7 +1635,7 @@ static const struct command_registration svf_command_handlers[] = { .handler = handle_svf_command, .mode = COMMAND_EXEC, .help = "Runs a SVF file.", - .usage = "[-tap device.tap] [quiet] [nil] [progress] [ignore_error] [-noreset] [-addcycles numcycles]", + .usage = "[-tap device.tap] [-quiet] [-nil] [-progress] [-ignore_error] [-noreset] [-addcycles numcycles] file", }, COMMAND_REGISTRATION_DONE }; From 1ec8b83cbdb407536966b4e455dbb39d1cb42b3a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 00:01:00 +0100 Subject: [PATCH 07/50] helper: command: rewrite command 'ocd_find' as COMMAND_HANDLER The mixed use of jim commands and OpenOCD commands is error prone due to handling of errors through JIM_xx and ERROR_yy. Rewrite the jim command 'ocd_find' as OpenOCD command. Change-Id: Id775bccc12840bcf95d8c19787beda5e7c3107fc Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7484 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/helper/command.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index b358e18aa4..235bec8580 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -662,19 +662,19 @@ void command_done(struct command_context *cmd_ctx) } /* find full path to file */ -static int jim_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_find) { - if (argc != 2) - return JIM_ERR; - const char *file = Jim_GetString(argv[1], NULL); - char *full_path = find_file(file); + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + char *full_path = find_file(CMD_ARGV[0]); if (!full_path) - return JIM_ERR; - Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path)); + return ERROR_COMMAND_ARGUMENT_INVALID; + + command_print(CMD, "%s", full_path); free(full_path); - Jim_SetResult(interp, result); - return JIM_OK; + return ERROR_OK; } COMMAND_HANDLER(handle_echo) @@ -1165,7 +1165,7 @@ static const struct command_registration command_builtin_handlers[] = { { .name = "ocd_find", .mode = COMMAND_ANY, - .jim_handler = jim_find, + .handler = handle_find, .help = "find full path to file", .usage = "file", }, From d05c68667129705ecfd42c6029a60e849518d50c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 18 Dec 2022 15:26:56 +0100 Subject: [PATCH 08/50] transport: rewrite command 'transport select' as COMMAND_HANDLER The mixed use of jim commands and OpenOCD commands is error prone due to handling of errors through JIM_xx and ERROR_yy. Rewrite the jim command 'transport select' as OpenOCD command. This fixes and incorrect check for the return value of function transport_select(); it returns ERROR_yy but the check is on JIM_xx. While there, fix the coding style. Change-Id: I9f3e8394c1a0cc0312b414c58275e1220217bbed Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7485 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/transport/transport.c | 100 +++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 51 deletions(-) diff --git a/src/transport/transport.c b/src/transport/transport.c index c05db3f005..81d3d583bc 100644 --- a/src/transport/transport.c +++ b/src/transport/transport.c @@ -252,64 +252,62 @@ COMMAND_HANDLER(handle_transport_list) * set supported by the debug adapter being used. Return value * is scriptable (allowing "if swd then..." etc). */ -static int jim_transport_select(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_transport_select) { - int res; - switch (argc) { - case 1: /* autoselect if necessary, then return/display current config */ - if (!session) { - if (!allowed_transports) { - LOG_ERROR("Debug adapter does not support any transports? Check config file order."); - return JIM_ERR; - } - LOG_INFO("auto-selecting first available session transport \"%s\". " - "To override use 'transport select '.", allowed_transports[0]); - res = transport_select(global_cmd_ctx, allowed_transports[0]); - if (res != JIM_OK) - return res; - } - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - case 2: /* assign */ - if (session) { - if (!strcmp(session->name, argv[1]->bytes)) { - LOG_WARNING("Transport \"%s\" was already selected", session->name); - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - } else { - LOG_ERROR("Can't change session's transport after the initial selection was made"); - return JIM_ERR; - } - } + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; - /* Is this transport supported by our debug adapter? - * Example, "JTAG-only" means SWD is not supported. - * - * NOTE: requires adapter to have been set up, with - * transports declared via C. - */ + if (CMD_ARGC == 0) { + /* autoselect if necessary, then return/display current config */ + if (!session) { if (!allowed_transports) { - LOG_ERROR("Debug adapter doesn't support any transports?"); - return JIM_ERR; + command_print(CMD, "Debug adapter does not support any transports? Check config file order."); + return ERROR_FAIL; } + LOG_INFO("auto-selecting first available session transport \"%s\". " + "To override use 'transport select '.", allowed_transports[0]); + int retval = transport_select(CMD_CTX, allowed_transports[0]); + if (retval != ERROR_OK) + return retval; + } + command_print(CMD, "%s", session->name); + return ERROR_OK; + } - for (unsigned i = 0; allowed_transports[i]; i++) { + /* assign transport */ + if (session) { + if (!strcmp(session->name, CMD_ARGV[0])) { + LOG_WARNING("Transport \"%s\" was already selected", session->name); + command_print(CMD, "%s", session->name); + return ERROR_OK; + } + command_print(CMD, "Can't change session's transport after the initial selection was made"); + return ERROR_FAIL; + } - if (strcmp(allowed_transports[i], argv[1]->bytes) == 0) { - if (transport_select(global_cmd_ctx, argv[1]->bytes) == ERROR_OK) { - Jim_SetResultString(interp, session->name, -1); - return JIM_OK; - } - return JIM_ERR; - } - } + /* Is this transport supported by our debug adapter? + * Example, "JTAG-only" means SWD is not supported. + * + * NOTE: requires adapter to have been set up, with + * transports declared via C. + */ + if (!allowed_transports) { + command_print(CMD, "Debug adapter doesn't support any transports?"); + return ERROR_FAIL; + } - LOG_ERROR("Debug adapter doesn't support '%s' transport", argv[1]->bytes); - return JIM_ERR; - default: - Jim_WrongNumArgs(interp, 1, argv, "[too many parameters]"); - return JIM_ERR; + for (unsigned int i = 0; allowed_transports[i]; i++) { + if (!strcmp(allowed_transports[i], CMD_ARGV[0])) { + int retval = transport_select(CMD_CTX, CMD_ARGV[0]); + if (retval != ERROR_OK) + return retval; + command_print(CMD, "%s", session->name); + return ERROR_OK; + } } + + command_print(CMD, "Debug adapter doesn't support '%s' transport", CMD_ARGV[0]); + return ERROR_FAIL; } static const struct command_registration transport_commands[] = { @@ -333,7 +331,7 @@ static const struct command_registration transport_commands[] = { }, { .name = "select", - .jim_handler = jim_transport_select, + .handler = handle_transport_select, .mode = COMMAND_ANY, .help = "Select this session's transport", .usage = "[transport_name]", From 80fc9fabc66a0bc767467fa14c703e5a9f340cd3 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 18 Dec 2022 16:09:02 +0100 Subject: [PATCH 09/50] flash: nor: rewrite command 'flash list' as COMMAND_HANDLER The mixed use of jim commands and OpenOCD commands is error prone due to handling of errors through JIM_xx and ERROR_yy. Rewrite the jim command 'flash list' as OpenOCD command. While there: - format in a human readable way the output dictionary list, while preserving the structure of its TCL data; - add the mandatory 'usage' field. Change-Id: I1ee69870d3ab3c1cfc46cd2b8ec03de6b2300bd6 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7486 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/flash/nor/tcl.c | 48 +++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 4ff6d98386..ecbcf00aaa 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -1324,40 +1324,27 @@ COMMAND_HANDLER(handle_flash_banks_command) return ERROR_OK; } -static int jim_flash_list(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_flash_list) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, - "no arguments to 'flash list' command"); - return JIM_ERR; - } - - Jim_Obj *list = Jim_NewListObj(interp, NULL, 0); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; for (struct flash_bank *p = flash_bank_list(); p; p = p->next) { - Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0); - - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->name, -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "driver", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "target", -1)); - Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, target_name(p->target), -1)); - - Jim_ListAppendElement(interp, list, elem); + command_print(CMD, + "{\n" + " name %s\n" + " driver %s\n" + " base " TARGET_ADDR_FMT "\n" + " size 0x%" PRIx32 "\n" + " bus_width %u\n" + " chip_width %u\n" + " target %s\n" + "}", + p->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width, + target_name(p->target)); } - Jim_SetResult(interp, list); - - return JIM_OK; + return ERROR_OK; } COMMAND_HANDLER(handle_flash_init_command) @@ -1404,8 +1391,9 @@ static const struct command_registration flash_config_command_handlers[] = { { .name = "list", .mode = COMMAND_ANY, - .jim_handler = jim_flash_list, + .handler = handle_flash_list, .help = "Returns a list of details about the flash banks.", + .usage = "", }, COMMAND_REGISTRATION_DONE }; From 842a12f4caf307e756045c14011c402a20da30b6 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 18 Dec 2022 18:49:02 +0100 Subject: [PATCH 10/50] helper: util: rewrite command 'ms' as COMMAND_HANDLER Use full 64 bits in output; no reason to truncate at 32 bits. Change-Id: I433815a381e147731ff0da2c805170649a9bcf38 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7487 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/helper/util.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/helper/util.c b/src/helper/util.c index bf18f8e603..5e12021ff5 100644 --- a/src/helper/util.c +++ b/src/helper/util.c @@ -13,28 +13,21 @@ #include "log.h" #include "time_support.h" -static int jim_util_ms(Jim_Interp *interp, - int argc, - Jim_Obj * const *argv) +COMMAND_HANDLER(handler_util_ms) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "ls ?dir?"); - return JIM_ERR; - } + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - /* Cast from 64 to 32 bit int works for 2's-compliment - * when calculating differences*/ - Jim_SetResult(interp, Jim_NewIntObj(interp, (int)timeval_ms())); + command_print(CMD, "%" PRId64, timeval_ms()); - return JIM_OK; + return ERROR_OK; } static const struct command_registration util_command_handlers[] = { - /* jim handlers */ { .name = "ms", .mode = COMMAND_ANY, - .jim_handler = jim_util_ms, + .handler = handler_util_ms, .help = "Returns ever increasing milliseconds. Used to calculate differences in time.", .usage = "", From 880ae3f07744a09e267bde00cf405c85a6f10482 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 18 Dec 2022 19:12:35 +0100 Subject: [PATCH 11/50] openocd: rewrite command 'version' as COMMAND_HANDLER Trivial change. While there: - add the mandatory 'usage' field; - document the optional parameter 'git'; - reword the documentation. Change-Id: I6be4d4423128fa026a62e2ef355f77b69d50397e Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7488 Tested-by: jenkins --- doc/openocd.texi | 6 ++++-- src/openocd.c | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 26a59e6a72..67661845d0 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -9101,8 +9101,10 @@ format. Optional @option{start} and @option{end} parameters allow to limit the address range. @end deffn -@deffn {Command} {version} -Displays a string identifying the version of this OpenOCD server. +@deffn {Command} {version} [git] +Returns a string identifying the version of this OpenOCD server. +With option @option{git}, it returns the git version obtained at compile time +through ``git describe''. @end deffn @deffn {Command} {virt2phys} virtual_address diff --git a/src/openocd.c b/src/openocd.c index 875da5a62c..54c5eb34f7 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -51,24 +51,23 @@ static const char openocd_startup_tcl[] = { }; /* Give scripts and TELNET a way to find out what version this is */ -static int jim_version_command(Jim_Interp *interp, int argc, - Jim_Obj * const *argv) +COMMAND_HANDLER(handler_version_command) { - if (argc > 2) - return JIM_ERR; - const char *str = ""; - char *version_str; - version_str = OPENOCD_VERSION; + char *version_str = OPENOCD_VERSION; - if (argc == 2) - str = Jim_GetString(argv[1], NULL); + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 1) { + if (strcmp("git", CMD_ARGV[0])) + return ERROR_COMMAND_ARGUMENT_INVALID; - if (strcmp("git", str) == 0) version_str = GITVERSION; + } - Jim_SetResult(interp, Jim_NewStringObj(interp, version_str, -1)); + command_print(CMD, "%s", version_str); - return JIM_OK; + return ERROR_OK; } static int log_target_callback_event_handler(struct target *target, @@ -194,9 +193,10 @@ COMMAND_HANDLER(handle_add_script_search_dir_command) static const struct command_registration openocd_command_handlers[] = { { .name = "version", - .jim_handler = jim_version_command, + .handler = handler_version_command, .mode = COMMAND_ANY, .help = "show program version", + .usage = "[git]", }, { .name = "noinit", From 0332da1f1518b0cb4150965614c09fcc7319ddbe Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 18 Dec 2022 22:42:18 +0100 Subject: [PATCH 12/50] rtt: rewrite command 'rtt channellist' as COMMAND_HANDLER This also fixes a mistake of the jim command returning ERROR_xx when function rtt_read_channel_info() returns error. While there: - format in a human readable way the output dictionary list, while preserving the structure of its TCL data; - add check for the number of parameters. Change-Id: Ica2b623699d3a606d3992975c836dae96f74b26d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7489 Tested-by: jenkins --- src/rtt/tcl.c | 86 ++++++++++++++++----------------------------------- 1 file changed, 26 insertions(+), 60 deletions(-) diff --git a/src/rtt/tcl.c b/src/rtt/tcl.c index 7cbdccf567..f949aa1c94 100644 --- a/src/rtt/tcl.c +++ b/src/rtt/tcl.c @@ -150,17 +150,17 @@ COMMAND_HANDLER(handle_rtt_channels_command) return ERROR_OK; } -static int jim_channel_list(Jim_Interp *interp, int argc, - Jim_Obj * const *argv) +COMMAND_HANDLER(handle_channel_list) { - Jim_Obj *list; - Jim_Obj *channel_list; char channel_name[CHANNEL_NAME_SIZE]; const struct rtt_control *ctrl; struct rtt_channel_info info; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + if (!rtt_found_cb()) { - Jim_SetResultFormatted(interp, "rtt: Control block not available"); + command_print(CMD, "rtt: Control block not available"); return ERROR_FAIL; } @@ -169,81 +169,47 @@ static int jim_channel_list(Jim_Interp *interp, int argc, info.name = channel_name; info.name_length = sizeof(channel_name); - list = Jim_NewListObj(interp, NULL, 0); - channel_list = Jim_NewListObj(interp, NULL, 0); + command_print(CMD, "{"); for (unsigned int i = 0; i < ctrl->num_up_channels; i++) { - int ret; - Jim_Obj *tmp; - - ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info); - + int ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info); if (ret != ERROR_OK) return ret; if (!info.size) continue; - tmp = Jim_NewListObj(interp, NULL, 0); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "name", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - info.name, -1)); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "size", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, - info.size)); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "flags", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, - info.flags)); - - Jim_ListAppendElement(interp, channel_list, tmp); + command_print(CMD, + " {\n" + " name %s\n" + " size 0x%" PRIx32 "\n" + " flags 0x%" PRIx32 "\n" + " }", + info.name, info.size, info.flags); } - Jim_ListAppendElement(interp, list, channel_list); - - channel_list = Jim_NewListObj(interp, NULL, 0); + command_print(CMD, "}\n{"); for (unsigned int i = 0; i < ctrl->num_down_channels; i++) { - int ret; - Jim_Obj *tmp; - - ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info); - + int ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info); if (ret != ERROR_OK) return ret; if (!info.size) continue; - tmp = Jim_NewListObj(interp, NULL, 0); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "name", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - info.name, -1)); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "size", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, - info.size)); - - Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp, - "flags", -1)); - Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp, - info.flags)); - - Jim_ListAppendElement(interp, channel_list, tmp); + command_print(CMD, + " {\n" + " name %s\n" + " size 0x%" PRIx32 "\n" + " flags 0x%" PRIx32 "\n" + " }", + info.name, info.size, info.flags); } - Jim_ListAppendElement(interp, list, channel_list); - Jim_SetResult(interp, list); + command_print(CMD, "}"); - return JIM_OK; + return ERROR_OK; } static const struct command_registration rtt_subcommand_handlers[] = { @@ -284,7 +250,7 @@ static const struct command_registration rtt_subcommand_handlers[] = { }, { .name = "channellist", - .jim_handler = jim_channel_list, + .handler = handle_channel_list, .mode = COMMAND_EXEC, .help = "list available channels", .usage = "" From 21e6252965d8cf82660344a7d6c12d64269d7387 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 12:49:20 +0100 Subject: [PATCH 13/50] target: aarch64: rewrite commands 'aarch64 mcr/mrc' as COMMAND_HANDLER This also fixes an incorrect return ERROR_TARGET_NOT_HALTED from a jim command. Change-Id: I99a02a21bedb64e60944e295c7cf24356e07be60 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7490 Tested-by: jenkins --- src/target/aarch64.c | 129 +++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 83 deletions(-) diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 8e90e64007..3c33032e97 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2952,53 +2952,41 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) return ERROR_OK; } -static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(aarch64_mcrmrc_command) { - struct command *c = jim_to_command(interp); - struct command_context *context; - struct target *target; - struct arm *arm; - int retval; bool is_mcr = false; - int arg_cnt = 0; + unsigned int arg_cnt = 5; - if (!strcmp(c->name, "mcr")) { + if (!strcmp(CMD_NAME, "mcr")) { is_mcr = true; - arg_cnt = 7; - } else { arg_cnt = 6; } - context = current_command_context(interp); - assert(context); + if (arg_cnt != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; - target = get_current_target(context); + struct target *target = get_current_target(CMD_CTX); if (!target) { - LOG_ERROR("%s: no current target", __func__); - return JIM_ERR; + command_print(CMD, "no current target"); + return ERROR_FAIL; } if (!target_was_examined(target)) { - LOG_ERROR("%s: not yet examined", target_name(target)); - return JIM_ERR; + command_print(CMD, "%s: not yet examined", target_name(target)); + return ERROR_TARGET_NOT_EXAMINED; } - arm = target_to_arm(target); + struct arm *arm = target_to_arm(target); if (!is_arm(arm)) { - LOG_ERROR("%s: not an ARM", target_name(target)); - return JIM_ERR; + command_print(CMD, "%s: not an ARM", target_name(target)); + return ERROR_FAIL; } if (target->state != TARGET_HALTED) return ERROR_TARGET_NOT_HALTED; if (arm->core_state == ARM_STATE_AARCH64) { - LOG_ERROR("%s: not 32-bit arm target", target_name(target)); - return JIM_ERR; - } - - if (argc != arg_cnt) { - LOG_ERROR("%s: wrong number of arguments", __func__); - return JIM_ERR; + command_print(CMD, "%s: not 32-bit arm target", target_name(target)); + return ERROR_FAIL; } int cpnum; @@ -3007,87 +2995,62 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) uint32_t crn; uint32_t crm; uint32_t value; - long l; /* NOTE: parameter sequence matches ARM instruction set usage: * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX * The "rX" is necessarily omitted; it uses Tcl mechanisms. */ - retval = Jim_GetLong(interp, argv[1], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "coprocessor", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum); + if (cpnum & ~0xf) { + command_print(CMD, "coprocessor %d out of range", cpnum); + return ERROR_COMMAND_ARGUMENT_INVALID; } - cpnum = l; - retval = Jim_GetLong(interp, argv[2], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op1", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1); + if (op1 & ~0x7) { + command_print(CMD, "op1 %d out of range", op1); + return ERROR_COMMAND_ARGUMENT_INVALID; } - op1 = l; - retval = Jim_GetLong(interp, argv[3], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRn", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn); + if (crn & ~0xf) { + command_print(CMD, "CRn %d out of range", crn); + return ERROR_COMMAND_ARGUMENT_INVALID; } - crn = l; - retval = Jim_GetLong(interp, argv[4], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRm", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm); + if (crm & ~0xf) { + command_print(CMD, "CRm %d out of range", crm); + return ERROR_COMMAND_ARGUMENT_INVALID; } - crm = l; - retval = Jim_GetLong(interp, argv[5], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op2", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2); + if (op2 & ~0x7) { + command_print(CMD, "op2 %d out of range", op2); + return ERROR_COMMAND_ARGUMENT_INVALID; } - op2 = l; - value = 0; - - if (is_mcr == true) { - retval = Jim_GetLong(interp, argv[6], &l); - if (retval != JIM_OK) - return retval; - value = l; + if (is_mcr) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value); /* NOTE: parameters reordered! */ /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); + int retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); if (retval != ERROR_OK) - return JIM_ERR; + return retval; } else { + value = 0; /* NOTE: parameters reordered! */ /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); + int retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); if (retval != ERROR_OK) - return JIM_ERR; + return retval; - Jim_SetResult(interp, Jim_NewIntObj(interp, value)); + command_print(CMD, "0x%" PRIx32, value); } - return JIM_OK; + return ERROR_OK; } static const struct command_registration aarch64_exec_command_handlers[] = { @@ -3122,14 +3085,14 @@ static const struct command_registration aarch64_exec_command_handlers[] = { { .name = "mcr", .mode = COMMAND_EXEC, - .jim_handler = jim_mcrmrc, + .handler = aarch64_mcrmrc_command, .help = "write coprocessor register", .usage = "cpnum op1 CRn CRm op2 value", }, { .name = "mrc", .mode = COMMAND_EXEC, - .jim_handler = jim_mcrmrc, + .handler = aarch64_mcrmrc_command, .help = "read coprocessor register", .usage = "cpnum op1 CRn CRm op2", }, From c4f2337d02d3c0d452a9958e44e82a8e6454dead Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 13:02:59 +0100 Subject: [PATCH 14/50] target: armv4_5: rewrite commands 'arm mcr/mrc' as COMMAND_HANDLER While there, add a check for target halted and check the number of parameters accordingly to the command name. Change-Id: I9e8bb109c35039561997d14782fac682267aee65 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7491 Tested-by: jenkins --- src/target/armv4_5.c | 132 +++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 79 deletions(-) diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 48af5035a0..9586adc977 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -989,36 +989,37 @@ COMMAND_HANDLER(handle_arm_disassemble_command) #endif } -static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_armv4_5_mcrmrc) { - struct command_context *context; - struct target *target; - struct arm *arm; - int retval; + bool is_mcr = false; + unsigned int arg_cnt = 5; + + if (!strcmp(CMD_NAME, "mcr")) { + is_mcr = true; + arg_cnt = 6; + } - context = current_command_context(interp); - assert(context); + if (arg_cnt != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; - target = get_current_target(context); + struct target *target = get_current_target(CMD_CTX); if (!target) { - LOG_ERROR("%s: no current target", __func__); - return JIM_ERR; + command_print(CMD, "no current target"); + return ERROR_FAIL; } if (!target_was_examined(target)) { - LOG_ERROR("%s: not yet examined", target_name(target)); - return JIM_ERR; + command_print(CMD, "%s: not yet examined", target_name(target)); + return ERROR_TARGET_NOT_EXAMINED; } - arm = target_to_arm(target); + + struct arm *arm = target_to_arm(target); if (!is_arm(arm)) { - LOG_ERROR("%s: not an ARM", target_name(target)); - return JIM_ERR; + command_print(CMD, "%s: not an ARM", target_name(target)); + return ERROR_FAIL; } - if ((argc < 6) || (argc > 7)) { - /* FIXME use the command name to verify # params... */ - LOG_ERROR("%s: wrong number of arguments", __func__); - return JIM_ERR; - } + if (target->state != TARGET_HALTED) + return ERROR_TARGET_NOT_HALTED; int cpnum; uint32_t op1; @@ -1026,95 +1027,68 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) uint32_t crn; uint32_t crm; uint32_t value; - long l; /* NOTE: parameter sequence matches ARM instruction set usage: * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX * The "rX" is necessarily omitted; it uses Tcl mechanisms. */ - retval = Jim_GetLong(interp, argv[1], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "coprocessor", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum); + if (cpnum & ~0xf) { + command_print(CMD, "coprocessor %d out of range", cpnum); + return ERROR_COMMAND_ARGUMENT_INVALID; } - cpnum = l; - retval = Jim_GetLong(interp, argv[2], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op1", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1); + if (op1 & ~0x7) { + command_print(CMD, "op1 %d out of range", op1); + return ERROR_COMMAND_ARGUMENT_INVALID; } - op1 = l; - retval = Jim_GetLong(interp, argv[3], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRn", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn); + if (crn & ~0xf) { + command_print(CMD, "CRn %d out of range", crn); + return ERROR_COMMAND_ARGUMENT_INVALID; } - crn = l; - retval = Jim_GetLong(interp, argv[4], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0xf) { - LOG_ERROR("%s: %s %d out of range", __func__, - "CRm", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm); + if (crm & ~0xf) { + command_print(CMD, "CRm %d out of range", crm); + return ERROR_COMMAND_ARGUMENT_INVALID; } - crm = l; - retval = Jim_GetLong(interp, argv[5], &l); - if (retval != JIM_OK) - return retval; - if (l & ~0x7) { - LOG_ERROR("%s: %s %d out of range", __func__, - "op2", (int) l); - return JIM_ERR; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2); + if (op2 & ~0x7) { + command_print(CMD, "op2 %d out of range", op2); + return ERROR_COMMAND_ARGUMENT_INVALID; } - op2 = l; - - value = 0; - /* FIXME don't assume "mrc" vs "mcr" from the number of params; - * that could easily be a typo! Check both... - * + /* * FIXME change the call syntax here ... simplest to just pass * the MRC() or MCR() instruction to be executed. That will also * let us support the "mrc2" and "mcr2" opcodes (toggling one bit) * if that's ever needed. */ - if (argc == 7) { - retval = Jim_GetLong(interp, argv[6], &l); - if (retval != JIM_OK) - return retval; - value = l; + if (is_mcr) { + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value); /* NOTE: parameters reordered! */ /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); + int retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value); if (retval != ERROR_OK) - return JIM_ERR; + return retval; } else { + value = 0; /* NOTE: parameters reordered! */ /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */ - retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); + int retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value); if (retval != ERROR_OK) - return JIM_ERR; + return retval; - Jim_SetResult(interp, Jim_NewIntObj(interp, value)); + command_print(CMD, "0x%" PRIx32, value); } - return JIM_OK; + return ERROR_OK; } static const struct command_registration arm_exec_command_handlers[] = { @@ -1128,14 +1102,14 @@ static const struct command_registration arm_exec_command_handlers[] = { { .name = "mcr", .mode = COMMAND_EXEC, - .jim_handler = &jim_mcrmrc, + .handler = handle_armv4_5_mcrmrc, .help = "write coprocessor register", .usage = "cpnum op1 CRn CRm op2 value", }, { .name = "mrc", .mode = COMMAND_EXEC, - .jim_handler = &jim_mcrmrc, + .handler = handle_armv4_5_mcrmrc, .help = "read coprocessor register", .usage = "cpnum op1 CRn CRm op2", }, From 5da4ef25c8a2e57325bc1706c07f54cc99ce0ce1 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 17:55:13 +0100 Subject: [PATCH 15/50] target: cti: rewrite command 'cti names' as COMMAND_HANDLER While there, format in a human readable way the output list by using one line per cti name. Change-Id: I6d4870ee512fe7e6935d73355c2377ad805ccc3b Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7492 Tested-by: jenkins --- src/target/arm_cti.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index 3612874e2a..7637ad0158 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -525,20 +525,17 @@ static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return cti_create(&goi); } -static int jim_cti_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(cti_handle_names) { struct arm_cti *obj; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - list_for_each_entry(obj, &all_cti, lh) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, obj->name, -1)); - } - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + list_for_each_entry(obj, &all_cti, lh) + command_print(CMD, "%s", obj->name); + + return ERROR_OK; } @@ -553,7 +550,7 @@ static const struct command_registration cti_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_cti_names, + .handler = cti_handle_names, .usage = "", .help = "Lists all registered CTI objects by name", }, From 19e2a0d6af3783e572a80e4cbf0f471f6dbf66e7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 18 Dec 2022 22:11:14 +0100 Subject: [PATCH 16/50] jtag: rewrite command 'adapter name' as COMMAND_HANDLER Trivial change. Add the mandatory 'usage' field. Change-Id: Id92af5cd873fb86f5de79f785f156d1ef734b005 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7493 Tested-by: jenkins --- src/jtag/adapter.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index eb73fcb9a3..76a6620be4 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -378,21 +378,18 @@ bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path return equal; } -static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_adapter_name) { - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - /* return the name of the interface */ /* TCL code might need to know the exact type... */ /* FUTURE: we allow this as a means to "set" the interface. */ - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - const char *name = adapter_driver ? adapter_driver->name : NULL; - Jim_SetResultString(goi.interp, name ? name : "undefined", -1); - return JIM_OK; + + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + command_print(CMD, "%s", adapter_driver ? adapter_driver->name : "undefined"); + + return ERROR_OK; } COMMAND_HANDLER(adapter_transports_command) @@ -1127,9 +1124,10 @@ static const struct command_registration adapter_command_handlers[] = { { .name = "name", .mode = COMMAND_ANY, - .jim_handler = jim_adapter_name, + .handler = handle_adapter_name, .help = "Returns the name of the currently " "selected adapter (driver)", + .usage = "", }, { .name = "srst", From 27741252571d7c34b9049275d02cf6c34b1ae7d2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 18:08:03 +0100 Subject: [PATCH 17/50] jtag: rewrite command 'jtag names' as COMMAND_HANDLER While there: - format in a human readable way the output list by using one line per tap name; - add the mandatory 'usage' field. Change-Id: I295449220c78fac8973478b265413342ea832f61 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7494 Tested-by: jenkins --- src/jtag/tcl.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index fc0d562e23..83cb0a18b8 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -805,24 +805,15 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return jtag_tap_configure_cmd(&goi, t); } -static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_jtag_names) { - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0)); - struct jtag_tap *tap; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - for (tap = jtag_all_taps(); tap; tap = tap->next_tap) { - Jim_ListAppendElement(goi.interp, - Jim_GetResult(goi.interp), - Jim_NewStringObj(goi.interp, - tap->dotted_name, -1)); - } - return JIM_OK; + for (struct jtag_tap *tap = jtag_all_taps(); tap; tap = tap->next_tap) + command_print(CMD, "%s", tap->dotted_name); + + return ERROR_OK; } COMMAND_HANDLER(handle_jtag_init_command) @@ -921,8 +912,9 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_jtag_names, + .handler = handle_jtag_names, .help = "Returns list of all JTAG tap names.", + .usage = "", }, { .chain = jtag_command_handlers_to_move, From ff0fdcf61427b76f1cfc9c3ecd551f058c0957d0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 18:18:48 +0100 Subject: [PATCH 18/50] jtag: rewrite command 'jtag arp_init' as COMMAND_HANDLER While there add the mandatory 'usage' field. Change-Id: I3491ed79d11c5a3e81cc9afd2423da14b8df72ff Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7495 Tested-by: jenkins --- src/jtag/tcl.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 83cb0a18b8..f154295dd4 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -664,22 +664,12 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e) } } -static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_jtag_arp_init) { - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - struct command_context *context = current_command_context(interp); - int e = jtag_init_inner(context); - if (e != ERROR_OK) { - Jim_Obj *obj = Jim_NewIntObj(goi.interp, e); - Jim_SetResultFormatted(goi.interp, "error: %#s", obj); - return JIM_ERR; - } - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + return jtag_init_inner(CMD_CTX); } static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -843,10 +833,11 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "arp_init", .mode = COMMAND_ANY, - .jim_handler = jim_jtag_arp_init, + .handler = handle_jtag_arp_init, .help = "Validates JTAG scan chain against the list of " "declared TAPs using just the four standard JTAG " "signals.", + .usage = "", }, { .name = "arp_init-reset", From 254598ba25265b79bac4a5e32fa2abb5d252d2cb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 18:23:11 +0100 Subject: [PATCH 19/50] jtag: rewrite command 'jtag arp_init-reset' as COMMAND_HANDLER While there add the mandatory 'usage' field. Change-Id: I316fb31e24e94985dcc724e428b0384be7ef5bdd Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7496 Tested-by: jenkins --- src/jtag/tcl.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index f154295dd4..c6ca048104 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -672,27 +672,18 @@ COMMAND_HANDLER(handle_jtag_arp_init) return jtag_init_inner(CMD_CTX); } -static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_jtag_arp_init_reset) { - int e = ERROR_OK; - struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc-1, argv + 1); - if (goi.argc != 0) { - Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); - return JIM_ERR; - } - struct command_context *context = current_command_context(interp); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + if (transport_is_jtag()) - e = jtag_init_reset(context); - else if (transport_is_swd()) - e = swd_init_reset(context); + return jtag_init_reset(CMD_CTX); - if (e != ERROR_OK) { - Jim_Obj *obj = Jim_NewIntObj(goi.interp, e); - Jim_SetResultFormatted(goi.interp, "error: %#s", obj); - return JIM_ERR; - } - return JIM_OK; + if (transport_is_swd()) + return swd_init_reset(CMD_CTX); + + return ERROR_OK; } int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -842,9 +833,10 @@ static const struct command_registration jtag_subcommand_handlers[] = { { .name = "arp_init-reset", .mode = COMMAND_ANY, - .jim_handler = jim_jtag_arp_init_reset, + .handler = handle_jtag_arp_init_reset, .help = "Uses TRST and SRST to try resetting everything on " - "the JTAG scan chain, then performs 'jtag arp_init'." + "the JTAG scan chain, then performs 'jtag arp_init'.", + .usage = "", }, { .name = "newtap", From fbb7a50cbd5b9cda29698b3192e2a4596b3a6371 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 18:29:08 +0100 Subject: [PATCH 20/50] jtag: rewrite command 'flush_count' as COMMAND_HANDLER While there: - check the number of command parameters; - add the mandatory 'usage' field. Change-Id: I7cd16f049753caedf19f313f7dc84be98efdba42 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7497 Tested-by: jenkins --- src/jtag/tcl.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index c6ca048104..b3cbc48b49 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -249,12 +249,15 @@ static int jim_command_pathmove(Jim_Interp *interp, int argc, Jim_Obj * const *a return JIM_OK; } - -static int jim_command_flush_count(Jim_Interp *interp, int argc, Jim_Obj * const *args) +COMMAND_HANDLER(handle_jtag_flush_count) { - Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count())); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - return JIM_OK; + int count = jtag_get_flush_queue_count(); + command_print_sameline(CMD, "%d", count); + + return ERROR_OK; } /* REVISIT Just what about these should "move" ... ? @@ -279,9 +282,10 @@ static const struct command_registration jtag_command_handlers_to_move[] = { { .name = "flush_count", .mode = COMMAND_EXEC, - .jim_handler = jim_command_flush_count, + .handler = handle_jtag_flush_count, .help = "Returns the number of times the JTAG queue " "has been flushed.", + .usage = "", }, { .name = "pathmove", From f76e67a440bb1761b90ea0cab89e0422a4224779 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 18:35:23 +0100 Subject: [PATCH 21/50] target: arm_dap: rewrite command 'dap names' as COMMAND_HANDLER While there, format in a human readable way the output list by using one line per dap name. Change-Id: I24a47350105b90db15808c61790f05d807120739 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7498 Tested-by: jenkins --- src/target/arm_dap.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index e21136dd69..bc9d962363 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -421,20 +421,16 @@ static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return dap_create(&goi); } -static int jim_dap_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_dap_names) { + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + struct arm_dap_object *obj; + list_for_each_entry(obj, &all_dap, lh) + command_print(CMD, "%s", obj->name); - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - list_for_each_entry(obj, &all_dap, lh) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, obj->name, -1)); - } - return JIM_OK; + return ERROR_OK; } COMMAND_HANDLER(handle_dap_init) @@ -500,7 +496,7 @@ static const struct command_registration dap_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_dap_names, + .handler = handle_dap_names, .usage = "", .help = "Lists all registered DAP instances by name", }, From 8fa6db6e8e992793f5dcc23a7182e2b0cb70257e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 20:28:56 +0100 Subject: [PATCH 22/50] target: arm_tpiu_swo: rewrite command 'tpiu disable' as COMMAND_HANDLER Change-Id: I689482f898bde2afa2881b2f311676a6b98abb9a Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7499 Tested-by: jenkins --- src/target/arm_tpiu_swo.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index 7096db3055..897a9316c7 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -820,18 +820,15 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const return JIM_ERR; } -static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_arm_tpiu_swo_disable) { - struct command *c = jim_to_command(interp); - struct arm_tpiu_swo_object *obj = c->jim_handler_data; + struct arm_tpiu_swo_object *obj = CMD_DATA; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; if (!obj->enabled) - return JIM_OK; + return ERROR_OK; obj->enabled = false; arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE); @@ -845,20 +842,19 @@ static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const int retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL); if (retval != ERROR_OK) { - LOG_ERROR("Failed to stop adapter's trace"); - return JIM_ERR; + command_print(CMD, "Failed to stop adapter's trace"); + return retval; } } arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE); /* START_DEPRECATED_TPIU */ - struct command_context *cmd_ctx = current_command_context(interp); - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); target_handle_event(target, TARGET_EVENT_TRACE_CONFIG); /* END_DEPRECATED_TPIU */ - return JIM_OK; + return ERROR_OK; } static const struct command_registration arm_tpiu_swo_instance_command_handlers[] = { @@ -893,7 +889,7 @@ static const struct command_registration arm_tpiu_swo_instance_command_handlers[ { .name = "disable", .mode = COMMAND_EXEC, - .jim_handler = jim_arm_tpiu_swo_disable, + .handler = handle_arm_tpiu_swo_disable, .usage = "", .help = "Disables the TPIU/SWO output", }, From 5d39a8852ab604bed29d9e0d28da2cb5f7a87958 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 20:52:51 +0100 Subject: [PATCH 23/50] target: arm_tpiu_swo: rewrite command 'tpiu enable' as COMMAND_HANDLER Change-Id: Ia600948b99a229ef0490b7f576df62f880db8546 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7500 Tested-by: jenkins --- src/target/arm_tpiu_swo.c | 94 +++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index 897a9316c7..3cf306377c 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -595,54 +595,52 @@ static const struct service_driver arm_tpiu_swo_service_driver = { .keep_client_alive_handler = NULL, }; -static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_arm_tpiu_swo_enable) { - struct command *c = jim_to_command(interp); - struct arm_tpiu_swo_object *obj = c->jim_handler_data; - struct command_context *cmd_ctx = current_command_context(interp); + struct arm_tpiu_swo_object *obj = CMD_DATA; uint32_t value; int retval; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - if (cmd_ctx->mode == COMMAND_CONFIG) { + if (CMD_CTX->mode == COMMAND_CONFIG) { LOG_DEBUG("%s: enable deferred", obj->name); obj->deferred_enable = true; - return JIM_OK; + return ERROR_OK; } if (obj->enabled) - return JIM_OK; + return ERROR_OK; if (transport_is_hla() && obj->spot.ap_num != 0) { - LOG_ERROR("Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", obj->spot.ap_num); - return JIM_ERR; + command_print(CMD, + "Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", + obj->spot.ap_num); + return ERROR_FAIL; } if (!obj->traceclkin_freq) { - LOG_ERROR("Trace clock-in frequency not set"); - return JIM_ERR; + command_print(CMD, "Trace clock-in frequency not set"); + return ERROR_FAIL; } if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) if (!obj->swo_pin_freq) LOG_DEBUG("SWO pin frequency not set, will be autodetected by the adapter"); - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); /* START_DEPRECATED_TPIU */ if (obj->recheck_ap_cur_target) { if (strcmp(target->type->name, "cortex_m") && strcmp(target->type->name, "hla_target")) { LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA"); - return JIM_ERR; + return ERROR_FAIL; } if (!target_was_examined(target)) { LOG_ERROR(MSG "Current target not examined yet"); - return JIM_ERR; + return ERROR_FAIL; } struct cortex_m_common *cm = target_to_cm(target); obj->recheck_ap_cur_target = false; @@ -660,8 +658,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const if (!obj->ap) { obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num); if (!obj->ap) { - LOG_ERROR("Cannot get AP"); - return JIM_ERR; + command_print(CMD, "Cannot get AP"); + return ERROR_FAIL; } } @@ -670,8 +668,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value); if (retval != ERROR_OK) { - LOG_ERROR("Unable to read %s", obj->name); - return JIM_ERR; + command_print(CMD, "Unable to read %s", obj->name); + return retval; } switch (obj->pin_protocol) { case TPIU_SPPR_PROTOCOL_SYNC: @@ -687,21 +685,20 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const value = 0; } if (!value) { - struct jim_nvp *p; - jim_nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p); - LOG_ERROR("%s does not support protocol %s", obj->name, p->name); - return JIM_ERR; + struct jim_nvp *p = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol); + command_print(CMD, "%s does not support protocol %s", obj->name, p->name); + return ERROR_FAIL; } if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) { retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value); if (retval != ERROR_OK) { - LOG_ERROR("Cannot read TPIU register SSPSR"); - return JIM_ERR; + command_print(CMD, "Cannot read TPIU register SSPSR"); + return retval; } if (!(value & BIT(obj->port_width - 1))) { - LOG_ERROR("TPIU does not support port-width of %d bits", obj->port_width); - return JIM_ERR; + command_print(CMD, "TPIU does not support port-width of %d bits", obj->port_width); + return ERROR_FAIL; } } @@ -713,41 +710,42 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const struct arm_tpiu_swo_priv_connection *priv = malloc(sizeof(*priv)); if (!priv) { LOG_ERROR("Out of memory"); - return JIM_ERR; + return ERROR_FAIL; } priv->obj = obj; LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]); retval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1], CONNECTION_LIMIT_UNLIMITED, priv); if (retval != ERROR_OK) { - LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]); - return JIM_ERR; + command_print(CMD, "Can't configure trace TCP port %s", &obj->out_filename[1]); + return retval; } } else if (strcmp(obj->out_filename, "-")) { obj->file = fopen(obj->out_filename, "ab"); if (!obj->file) { - LOG_ERROR("Can't open trace destination file \"%s\"", obj->out_filename); - return JIM_ERR; + command_print(CMD, "Can't open trace destination file \"%s\"", obj->out_filename); + return ERROR_FAIL; } } retval = adapter_config_trace(true, obj->pin_protocol, obj->port_width, &swo_pin_freq, obj->traceclkin_freq, &prescaler); if (retval != ERROR_OK) { - LOG_ERROR("Failed to start adapter's trace"); + command_print(CMD, "Failed to start adapter's trace"); arm_tpiu_swo_close_output(obj); - return JIM_ERR; + return retval; } if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) if (!swo_pin_freq) { if (obj->swo_pin_freq) - LOG_ERROR("Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq); + command_print(CMD, "Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq); else - LOG_ERROR("Adapter does not support auto-detection of SWO pin frequency nor a default value"); + command_print(CMD, + "Adapter does not support auto-detection of SWO pin frequency nor a default value"); arm_tpiu_swo_close_output(obj); - return JIM_ERR; + return ERROR_FAIL; } if (obj->swo_pin_freq != swo_pin_freq) @@ -799,10 +797,10 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const /* END_DEPRECATED_TPIU */ obj->enabled = true; - return JIM_OK; + return ERROR_OK; error_exit: - LOG_ERROR("Error!"); + command_print(CMD, "Error!"); if (obj->en_capture) { obj->en_capture = false; @@ -811,13 +809,11 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj); - retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL); - if (retval != ERROR_OK) { - LOG_ERROR("Failed to stop adapter's trace"); - return JIM_ERR; - } + int retval1 = adapter_config_trace(false, 0, 0, NULL, 0, NULL); + if (retval1 != ERROR_OK) + command_print(CMD, "Failed to stop adapter's trace"); } - return JIM_ERR; + return retval; } COMMAND_HANDLER(handle_arm_tpiu_swo_disable) @@ -882,7 +878,7 @@ static const struct command_registration arm_tpiu_swo_instance_command_handlers[ { .name = "enable", .mode = COMMAND_ANY, - .jim_handler = jim_arm_tpiu_swo_enable, + .handler = handle_arm_tpiu_swo_enable, .usage = "", .help = "Enables the TPIU/SWO output", }, From 90ddac12e38ab21b1d3934235e0d1242e0f13616 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 20:56:40 +0100 Subject: [PATCH 24/50] target: arm_tpiu_swo: rewrite command 'tpiu names' as COMMAND_HANDLER While there, format in a human readable way the output list by using one line per tpiu name. Change-Id: I937c92b6c1e92509cf8aa96be1517a51bc363600 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7501 Tested-by: jenkins --- src/target/arm_tpiu_swo.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index 3cf306377c..55201e6fe0 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -981,20 +981,17 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const return JIM_ERR; } -static int jim_arm_tpiu_swo_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_arm_tpiu_swo_names) { struct arm_tpiu_swo_object *obj; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - list_for_each_entry(obj, &all_tpiu_swo, lh) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, obj->name, -1)); - } - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + list_for_each_entry(obj, &all_tpiu_swo, lh) + command_print(CMD, "%s", obj->name); + + return ERROR_OK; } static int jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -1185,7 +1182,7 @@ static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_arm_tpiu_swo_names, + .handler = handle_arm_tpiu_swo_names, .usage = "", .help = "Lists all registered TPIU and SWO objects by name", }, From 6f8c27dcfc51c3775f11785711d44563adb6eb17 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 21:00:42 +0100 Subject: [PATCH 25/50] target: arm_tpiu_swo: rewrite command 'tpiu init' as COMMAND_HANDLER Change-Id: Iaaccfc62dd85267066a152c434f254d1b9a0c4f1 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7502 Tested-by: jenkins --- src/target/arm_tpiu_swo.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index 55201e6fe0..5cea682ec4 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -994,23 +994,21 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_names) return ERROR_OK; } -static int jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_arm_tpiu_swo_init) { - struct command_context *cmd_ctx = current_command_context(interp); struct arm_tpiu_swo_object *obj; - int retval = JIM_OK; + int retval = ERROR_OK; + + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } list_for_each_entry(obj, &all_tpiu_swo, lh) { if (!obj->deferred_enable) continue; LOG_DEBUG("%s: running enable during init", obj->name); - int retval2 = command_run_linef(cmd_ctx, "%s enable", obj->name); + int retval2 = command_run_linef(CMD_CTX, "%s enable", obj->name); if (retval2 != ERROR_OK) - retval = JIM_ERR; + retval = retval2; } return retval; } @@ -1189,7 +1187,7 @@ static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = { { .name = "init", .mode = COMMAND_EXEC, - .jim_handler = jim_arm_tpiu_swo_init, + .handler = handle_arm_tpiu_swo_init, .usage = "", .help = "Initialize TPIU and SWO", }, From 584986ab1c9902fb58d928c1cb4ae885989fecbf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 23:15:54 +0100 Subject: [PATCH 26/50] target: rewrite command 'read_memory' as COMMAND_HANDLER While there, fix typo on 'exceeds'. In a following patch, the output could be formatted and split in N values per line to make it easier to read by humans. Change-Id: I295111a80934393011e46311f6cf6c13f2bdc0a3 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7503 Tested-by: jenkins --- src/target/target.c | 110 ++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 71 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index ae419ac8b2..07c3c29a4a 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -4592,57 +4592,36 @@ static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, return e; } -static int target_jim_read_memory(Jim_Interp *interp, int argc, - Jim_Obj * const *argv) +COMMAND_HANDLER(handle_target_read_memory) { /* - * argv[1] = memory address - * argv[2] = desired element width in bits - * argv[3] = number of elements to read - * argv[4] = optional "phys" + * CMD_ARGV[0] = memory address + * CMD_ARGV[1] = desired element width in bits + * CMD_ARGV[2] = number of elements to read + * CMD_ARGV[3] = optional "phys" */ - if (argc < 4 || argc > 5) { - Jim_WrongNumArgs(interp, 1, argv, "address width count ['phys']"); - return JIM_ERR; - } + if (CMD_ARGC < 3 || CMD_ARGC > 4) + return ERROR_COMMAND_SYNTAX_ERROR; /* Arg 1: Memory address. */ - jim_wide wide_addr; - int e; - e = Jim_GetWide(interp, argv[1], &wide_addr); - - if (e != JIM_OK) - return e; - - target_addr_t addr = (target_addr_t)wide_addr; + target_addr_t addr; + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], addr); /* Arg 2: Bit width of one element. */ - long l; - e = Jim_GetLong(interp, argv[2], &l); - - if (e != JIM_OK) - return e; - - const unsigned int width_bits = l; + unsigned int width_bits; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], width_bits); /* Arg 3: Number of elements to read. */ - e = Jim_GetLong(interp, argv[3], &l); - - if (e != JIM_OK) - return e; - - size_t count = l; + unsigned int count; + COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], count); /* Arg 4: Optional 'phys'. */ bool is_phys = false; - - if (argc > 4) { - const char *phys = Jim_GetString(argv[4], NULL); - - if (strcmp(phys, "phys")) { - Jim_SetResultFormatted(interp, "invalid argument '%s', must be 'phys'", phys); - return JIM_ERR; + if (CMD_ARGC == 4) { + if (strcmp(CMD_ARGV[3], "phys")) { + command_print(CMD, "invalid argument '%s', must be 'phys'", CMD_ARGV[3]); + return ERROR_COMMAND_ARGUMENT_INVALID; } is_phys = true; @@ -4655,37 +4634,33 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, case 64: break; default: - Jim_SetResultString(interp, "invalid width, must be 8, 16, 32 or 64", -1); - return JIM_ERR; + command_print(CMD, "invalid width, must be 8, 16, 32 or 64"); + return ERROR_COMMAND_ARGUMENT_INVALID; } const unsigned int width = width_bits / 8; if ((addr + (count * width)) < addr) { - Jim_SetResultString(interp, "read_memory: addr + count wraps to zero", -1); - return JIM_ERR; + command_print(CMD, "read_memory: addr + count wraps to zero"); + return ERROR_COMMAND_ARGUMENT_INVALID; } if (count > 65536) { - Jim_SetResultString(interp, "read_memory: too large read request, exeeds 64K elements", -1); - return JIM_ERR; + command_print(CMD, "read_memory: too large read request, exceeds 64K elements"); + return ERROR_COMMAND_ARGUMENT_INVALID; } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx != NULL); - struct target *target = get_current_target(cmd_ctx); + struct target *target = get_current_target(CMD_CTX); const size_t buffersize = 4096; uint8_t *buffer = malloc(buffersize); if (!buffer) { LOG_ERROR("Failed to allocate memory"); - return JIM_ERR; + return ERROR_FAIL; } - Jim_Obj *result_list = Jim_NewListObj(interp, NULL, 0); - Jim_IncrRefCount(result_list); - + char *separator = ""; while (count > 0) { const unsigned int max_chunk_len = buffersize / width; const size_t chunk_len = MIN(count, max_chunk_len); @@ -4698,11 +4673,15 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, retval = target_read_memory(target, addr, width, chunk_len, buffer); if (retval != ERROR_OK) { - LOG_ERROR("read_memory: read at " TARGET_ADDR_FMT " with width=%u and count=%zu failed", + LOG_DEBUG("read_memory: read at " TARGET_ADDR_FMT " with width=%u and count=%zu failed", addr, width_bits, chunk_len); - Jim_SetResultString(interp, "read_memory: failed to read memory", -1); - e = JIM_ERR; - break; + /* + * FIXME: we append the errmsg to the list of value already read. + * Add a way to flush and replace old output, but LOG_DEBUG() it + */ + command_print(CMD, "read_memory: failed to read memory"); + free(buffer); + return retval; } for (size_t i = 0; i < chunk_len ; i++) { @@ -4723,11 +4702,8 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, break; } - char value_buf[19]; - snprintf(value_buf, sizeof(value_buf), "0x%" PRIx64, v); - - Jim_ListAppendElement(interp, result_list, - Jim_NewStringObj(interp, value_buf, -1)); + command_print_sameline(CMD, "%s0x%" PRIx64, separator, v); + separator = " "; } count -= chunk_len; @@ -4736,15 +4712,7 @@ static int target_jim_read_memory(Jim_Interp *interp, int argc, free(buffer); - if (e != JIM_OK) { - Jim_DecrRefCount(interp, result_list); - return e; - } - - Jim_SetResult(interp, result_list); - Jim_DecrRefCount(interp, result_list); - - return JIM_OK; + return ERROR_OK; } static int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t idx, uint64_t *val) @@ -6074,7 +6042,7 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "read_memory", .mode = COMMAND_EXEC, - .jim_handler = target_jim_read_memory, + .handler = handle_target_read_memory, .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory", .usage = "address width count ['phys']", }, @@ -7203,7 +7171,7 @@ static const struct command_registration target_exec_command_handlers[] = { { .name = "read_memory", .mode = COMMAND_EXEC, - .jim_handler = target_jim_read_memory, + .handler = handle_target_read_memory, .help = "Read Tcl list of 8/16/32/64 bit numbers from target memory", .usage = "address width count ['phys']", }, From 113ba58231683e8cba329bf83b96d2192c39ad93 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 23:25:21 +0100 Subject: [PATCH 27/50] target: rewrite command 'target curstate' as COMMAND_HANDLER While there, add the mandatory 'usage' field. Change-Id: Ibfda6f56a1450e2eb9ad3092d756de0778f4a092 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7504 Tested-by: jenkins --- src/target/target.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 07c3c29a4a..da9cab9040 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5904,18 +5904,19 @@ COMMAND_HANDLER(handle_target_event_list) command_print(CMD, "***END***"); return ERROR_OK; } -static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv) + +COMMAND_HANDLER(handle_target_current_state) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "[no parameters]"); - return JIM_ERR; - } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - Jim_SetResultString(interp, target_state_name(target), -1); - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + struct target *target = get_current_target(CMD_CTX); + + command_print(CMD, "%s", target_state_name(target)); + + return ERROR_OK; } + static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { struct jim_getopt_info goi; @@ -6063,8 +6064,9 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "curstate", .mode = COMMAND_EXEC, - .jim_handler = jim_target_current_state, + .handler = handle_target_current_state, .help = "displays the current state of this target", + .usage = "", }, { .name = "arp_examine", From cca64798f8f01f2f06dbc020113cf9497b56f68b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 23:37:07 +0100 Subject: [PATCH 28/50] target: rewrite command 'was_examined' as COMMAND_HANDLER Check for empty command line, add the mandatory 'usage' field. Change-Id: I3f59448458fe01268bf5f4293aea5adcbd6d8279 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7505 Tested-by: jenkins --- src/target/target.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index da9cab9040..264b85f218 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5716,14 +5716,16 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv return JIM_OK; } -static int jim_target_was_examined(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_target_was_examined) { - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - Jim_SetResultBool(interp, target_was_examined(target)); - return JIM_OK; + struct target *target = get_current_target(CMD_CTX); + + command_print(CMD, "%d", target_was_examined(target) ? 1 : 0); + + return ERROR_OK; } static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv) @@ -6078,8 +6080,9 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "was_examined", .mode = COMMAND_EXEC, - .jim_handler = jim_target_was_examined, + .handler = handle_target_was_examined, .help = "used internally for reset processing", + .usage = "", }, { .name = "examine_deferred", From 2dda0e37d91f3ba9345dc20253ac162ff449504d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 23:41:22 +0100 Subject: [PATCH 29/50] target: rewrite command 'examine_deferred' as COMMAND_HANDLER Check for empty command line, add the mandatory 'usage' field. Change-Id: I9c3606242ec3dda9026fe19222162a110e618bff Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7506 Tested-by: jenkins --- src/target/target.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 264b85f218..a2c857a95b 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5728,14 +5728,16 @@ COMMAND_HANDLER(handle_target_was_examined) return ERROR_OK; } -static int jim_target_examine_deferred(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_target_examine_deferred) { - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - Jim_SetResultBool(interp, target->defer_examine); - return JIM_OK; + struct target *target = get_current_target(CMD_CTX); + + command_print(CMD, "%d", target->defer_examine ? 1 : 0); + + return ERROR_OK; } static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -6087,8 +6089,9 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "examine_deferred", .mode = COMMAND_EXEC, - .jim_handler = jim_target_examine_deferred, + .handler = handle_target_examine_deferred, .help = "used internally for reset processing", + .usage = "", }, { .name = "arp_halt_gdb", From 583efa68f71b9ad8e06b8e1246af25fc6c70e052 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 23:44:04 +0100 Subject: [PATCH 30/50] target: rewrite command 'arp_halt_gdb' as COMMAND_HANDLER While there add the mandatory 'usage' field. Change-Id: I5389881dac25877dc32930ec36ee546e48ecc14d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7507 Tested-by: jenkins --- src/target/target.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index a2c857a95b..4e29146482 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5740,20 +5740,14 @@ COMMAND_HANDLER(handle_target_examine_deferred) return ERROR_OK; } -static int jim_target_halt_gdb(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_halt_gdb) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "[no parameters]"); - return JIM_ERR; - } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - if (target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT) != ERROR_OK) - return JIM_ERR; + struct target *target = get_current_target(CMD_CTX); - return JIM_OK; + return target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); } static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -6096,8 +6090,9 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "arp_halt_gdb", .mode = COMMAND_EXEC, - .jim_handler = jim_target_halt_gdb, + .handler = handle_target_halt_gdb, .help = "used internally for reset processing to halt GDB", + .usage = "", }, { .name = "arp_poll", From 26f457896c456c57a57719e484d055d444ba67ee Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 23:50:23 +0100 Subject: [PATCH 31/50] target: rewrite command 'target current' as COMMAND_HANDLER While there add the mandatory 'usage' field. Change-Id: I3e5b826ca58f7ade30a443ada0cb4a9cd9ea35c2 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7508 Tested-by: jenkins --- src/target/target.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 4e29146482..ae5f74cbf7 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -6365,19 +6365,16 @@ static int target_create(struct jim_getopt_info *goi) return JIM_OK; } -static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_current) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; - struct target *target = get_current_target_or_null(cmd_ctx); + struct target *target = get_current_target_or_null(CMD_CTX); if (target) - Jim_SetResultString(interp, target_name(target), -1); - return JIM_OK; + command_print(CMD, "%s", target_name(target)); + + return ERROR_OK; } static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -6522,8 +6519,9 @@ static const struct command_registration target_subcommand_handlers[] = { { .name = "current", .mode = COMMAND_ANY, - .jim_handler = jim_target_current, + .handler = handle_target_current, .help = "Returns the currently selected target", + .usage = "", }, { .name = "types", From d9d698103e974b2a94c611864cccb92359509b7d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 23:54:10 +0100 Subject: [PATCH 32/50] target: rewrite command 'target types' as COMMAND_HANDLER Print one entry per line. While there add the mandatory 'usage' field. Change-Id: I135556e12154e33fdbd0f71d89f6fe37c69813b7 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7509 Tested-by: jenkins --- src/target/target.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index ae5f74cbf7..b77a25a2a3 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -6377,18 +6377,15 @@ COMMAND_HANDLER(handle_target_current) return ERROR_OK; } -static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_types) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); - for (unsigned x = 0; target_types[x]; x++) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, target_types[x]->name, -1)); - } - return JIM_OK; + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + for (unsigned int x = 0; target_types[x]; x++) + command_print(CMD, "%s", target_types[x]->name); + + return ERROR_OK; } static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -6526,9 +6523,10 @@ static const struct command_registration target_subcommand_handlers[] = { { .name = "types", .mode = COMMAND_ANY, - .jim_handler = jim_target_types, + .handler = handle_target_types, .help = "Returns the available target types as " "a list of strings", + .usage = "", }, { .name = "names", From 12b405a4ac3dddd18e2fd822e135bb783cae0236 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 19 Dec 2022 23:58:01 +0100 Subject: [PATCH 33/50] target: rewrite command 'target names' as COMMAND_HANDLER Print one entry per line. While there add the mandatory 'usage' field. Change-Id: Ia832684817f3bdbfa4cb943cd97e3f9fb2605902 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7510 Tested-by: jenkins --- src/target/target.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index b77a25a2a3..3fdb34ec6f 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -6388,20 +6388,18 @@ COMMAND_HANDLER(handle_target_types) return ERROR_OK; } -static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_names) { - if (argc != 1) { - Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); - return JIM_ERR; - } - Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); + if (CMD_ARGC != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + struct target *target = all_targets; while (target) { - Jim_ListAppendElement(interp, Jim_GetResult(interp), - Jim_NewStringObj(interp, target_name(target), -1)); + command_print(CMD, "%s", target_name(target)); target = target->next; } - return JIM_OK; + + return ERROR_OK; } static struct target_list * @@ -6531,8 +6529,9 @@ static const struct command_registration target_subcommand_handlers[] = { { .name = "names", .mode = COMMAND_ANY, - .jim_handler = jim_target_names, + .handler = handle_target_names, .help = "Returns the names of all targets as a list of strings", + .usage = "", }, { .name = "smp", From e9a7221b68d0775d9c96c8a12a7a26e2729caf37 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 20 Dec 2022 00:11:41 +0100 Subject: [PATCH 34/50] target: rewrite command 'target smp' as COMMAND_HANDLER This also fixes an incorrect return ERROR_xx from a jim command, propagated from return value of rtos_smp_init(). Change-Id: Icf4893c00aabd8fadd60077c5e8a2e926f687518 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7511 Tested-by: jenkins --- src/target/target.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 3fdb34ec6f..47abd28231 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -6404,9 +6404,8 @@ COMMAND_HANDLER(handle_target_names) static struct target_list * __attribute__((warn_unused_result)) -create_target_list_node(Jim_Obj *const name) { - int len; - const char *targetname = Jim_GetString(name, &len); +create_target_list_node(const char *targetname) +{ struct target *target = get_target(targetname); LOG_DEBUG("%s ", targetname); if (!target) @@ -6422,7 +6421,8 @@ create_target_list_node(Jim_Obj *const name) { return new; } -static int get_target_with_common_rtos_type(struct list_head *lh, struct target **result) +static int get_target_with_common_rtos_type(struct command_invocation *cmd, + struct list_head *lh, struct target **result) { struct target *target = NULL; struct target_list *curr; @@ -6430,39 +6430,39 @@ static int get_target_with_common_rtos_type(struct list_head *lh, struct target struct rtos *curr_rtos = curr->target->rtos; if (curr_rtos) { if (target && target->rtos && target->rtos->type != curr_rtos->type) { - LOG_ERROR("Different rtos types in members of one smp target!"); - return JIM_ERR; + command_print(cmd, "Different rtos types in members of one smp target!"); + return ERROR_FAIL; } target = curr->target; } } *result = target; - return JIM_OK; + return ERROR_OK; } -static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +COMMAND_HANDLER(handle_target_smp) { static int smp_group = 1; - if (argc == 1) { + if (CMD_ARGC == 0) { LOG_DEBUG("Empty SMP target"); - return JIM_OK; + return ERROR_OK; } - LOG_DEBUG("%d", argc); - /* argv[1] = target to associate in smp - * argv[2] = target to associate in smp - * argv[3] ... + LOG_DEBUG("%d", CMD_ARGC); + /* CMD_ARGC[0] = target to associate in smp + * CMD_ARGC[1] = target to associate in smp + * CMD_ARGC[2] ... */ struct list_head *lh = malloc(sizeof(*lh)); if (!lh) { LOG_ERROR("Out of memory"); - return JIM_ERR; + return ERROR_FAIL; } INIT_LIST_HEAD(lh); - for (int i = 1; i < argc; i++) { - struct target_list *new = create_target_list_node(argv[i]); + for (unsigned int i = 0; i < CMD_ARGC; i++) { + struct target_list *new = create_target_list_node(CMD_ARGV[i]); if (new) list_add_tail(&new->lh, lh); } @@ -6476,14 +6476,13 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) smp_group++; struct target *rtos_target; - int retval = get_target_with_common_rtos_type(lh, &rtos_target); - if (retval == JIM_OK && rtos_target) + int retval = get_target_with_common_rtos_type(CMD, lh, &rtos_target); + if (retval == ERROR_OK && rtos_target) retval = rtos_smp_init(rtos_target); return retval; } - static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { struct jim_getopt_info goi; @@ -6536,7 +6535,7 @@ static const struct command_registration target_subcommand_handlers[] = { { .name = "smp", .mode = COMMAND_ANY, - .jim_handler = jim_target_smp, + .handler = handle_target_smp, .usage = "targetname1 targetname2 ...", .help = "gather several target in a smp list" }, From f0e8f7b790f6d945c35b4bb868cafee5fcea3a22 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 3 Mar 2023 12:26:46 +0100 Subject: [PATCH 35/50] tcl/board/calao-usb-a9260: fix and refactor broken support The old configuration files did not work because of a missing 'at91sam9260minimal.cfg' file. Also, the config files were placed wrongly. Update them, put them to the proper location, merge the two supported boards into one, remove now superfluous include, remove defunct web page, etc.. Tested with a Calao USB-A9G20 and a hacked 'device_desc' to match. Native support for it will come next. Signed-off-by: Wolfram Sang Change-Id: Iec578c8777c5a6134e132dbac17c2988c7634742 Reviewed-on: https://review.openocd.org/c/openocd/+/7522 Tested-by: jenkins Reviewed-by: Tomas Vanek --- tcl/board/calao-usb-a9260.cfg | 14 +++++++++++++ tcl/interface/calao-usb-a9260.cfg | 12 ----------- tcl/interface/ftdi/calao-usb-a9260-c01.cfg | 24 ---------------------- tcl/interface/ftdi/calao-usb-a9260-c02.cfg | 24 ---------------------- 4 files changed, 14 insertions(+), 60 deletions(-) create mode 100644 tcl/board/calao-usb-a9260.cfg delete mode 100644 tcl/interface/calao-usb-a9260.cfg delete mode 100644 tcl/interface/ftdi/calao-usb-a9260-c01.cfg delete mode 100644 tcl/interface/ftdi/calao-usb-a9260-c02.cfg diff --git a/tcl/board/calao-usb-a9260.cfg b/tcl/board/calao-usb-a9260.cfg new file mode 100644 index 0000000000..52fede0fa5 --- /dev/null +++ b/tcl/board/calao-usb-a9260.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# CALAO Systems USB-A9260 (C01 and C02) + +adapter driver ftdi +ftdi device_desc "USB-A9260" +ftdi vid_pid 0x0403 0x6001 0x0403 0x6010 +ftdi layout_init 0x0c08 0x0f1b +ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 +ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 + +transport select jtag + +source [find target/at91sam9260.cfg] diff --git a/tcl/interface/calao-usb-a9260.cfg b/tcl/interface/calao-usb-a9260.cfg deleted file mode 100644 index ff652ef8fb..0000000000 --- a/tcl/interface/calao-usb-a9260.cfg +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -# -# CALAO Systems USB-A9260 common -C01 -C02 setup -# -# http://www.calao-systems.com/ -# -# See calao-usb-a9260-c01.cfg and calao-usb-a9260-c02.cfg. -# - -adapter srst delay 200 -jtag_ntrst_delay 200 diff --git a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg b/tcl/interface/ftdi/calao-usb-a9260-c01.cfg deleted file mode 100644 index c84e778746..0000000000 --- a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -# -# CALAO Systems USB-A9260-C01 -# -# http://www.calao-systems.com/ -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -adapter driver ftdi -ftdi device_desc "USB-A9260" -ftdi vid_pid 0x0403 0x6010 - -ftdi layout_init 0x0c08 0x0f1b -ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 - -script interface/calao-usb-a9260.cfg -script target/at91sam9260minimal.cfg diff --git a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg b/tcl/interface/ftdi/calao-usb-a9260-c02.cfg deleted file mode 100644 index 9d79b26005..0000000000 --- a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -# -# CALAO Systems USB-A9260-C02 -# -# http://www.calao-systems.com/ -# - -echo "WARNING!" -echo "This file was not tested with real interface, but is assumed to work as this" -echo "interface uses the same layout as configs that were verified. Please report your" -echo "experience with this file to openocd-devel mailing list, so it could be marked" -echo "as working or fixed." - -adapter driver ftdi -ftdi device_desc "USB-A9260" -ftdi vid_pid 0x0403 0x6001 - -ftdi layout_init 0x0c08 0x0f1b -ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 -ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 - -script interface/calao-usb-a9260.cfg -script target/at91sam9260minimal.cfg From b939224ab6e6e28e5211aac0303951ae4fabaf1f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 5 Mar 2023 08:38:14 +0100 Subject: [PATCH 36/50] tcl/board: add Calao USB-A9G20 Add a basic config. Signed-off-by: Wolfram Sang Change-Id: Ie68e5fbb26b1c2f3028e561af0255fa71ec61828 Reviewed-on: https://review.openocd.org/c/openocd/+/7524 Tested-by: jenkins Reviewed-by: Tomas Vanek --- tcl/board/calao-usb-a9g20-c01.cfg | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tcl/board/calao-usb-a9g20-c01.cfg diff --git a/tcl/board/calao-usb-a9g20-c01.cfg b/tcl/board/calao-usb-a9g20-c01.cfg new file mode 100644 index 0000000000..6c4bd40fe9 --- /dev/null +++ b/tcl/board/calao-usb-a9g20-c01.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# CALAO Systems USB-A9G20-C01 + +adapter driver ftdi +ftdi device_desc "USB-A9G20" +ftdi vid_pid 0x0403 0x6010 +ftdi layout_init 0x0c08 0x0f1b +ftdi layout_signal nTRST -data 0x0100 -noe 0x0400 +ftdi layout_signal nSRST -data 0x0200 -noe 0x0800 + +transport select jtag + +source [find target/at91sam9g20.cfg] From c1b14d678fd77095ef5c076c0e927aeed6a753c7 Mon Sep 17 00:00:00 2001 From: panciyan Date: Mon, 20 Mar 2023 02:26:58 +0000 Subject: [PATCH 37/50] flash/nor: missing fileio_close. If the file read abnormally, need to close it which was opened before. Signed-off-by: panciyan Change-Id: I6142f154741dcd38088b7add2793219ee4dd2ae9 Reviewed-on: https://review.openocd.org/c/openocd/+/7546 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/tcl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index ecbcf00aaa..22c1710adc 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -814,6 +814,7 @@ COMMAND_HANDLER(handle_flash_write_bank_command) if (buf_cnt != length) { LOG_ERROR("Short read"); free(buffer); + fileio_close(fileio); return ERROR_FAIL; } From 4b9b55a832e43815a1dd1b219107a01a1beadc1e Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Sat, 25 Mar 2023 02:56:19 +0300 Subject: [PATCH 38/50] github/workflow: increase delete-tag-and-release version During setup job in the GH actions, GH tries to resolve all actions before starting to run the scripts. It can not find 0.2.0 version inside 'dev-drprasad/delete-tag-and-release 'repo and action fails. This patch fixes that error. Also, switched to the latest ubuntu image Hidapi version updated to 0.13.1 Signed-off-by: Erhan Kurubas Change-Id: I02af41f6189d5a28f874c9b008073d74de46b4ca Reviewed-on: https://review.openocd.org/c/openocd/+/7551 Tested-by: jenkins Reviewed-by: Antonio Borneo --- .github/workflows/snapshot.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index e5997a055b..b48388ef7c 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -8,7 +8,7 @@ name: OpenOCD Snapshot jobs: package: - runs-on: [ubuntu-18.04] + runs-on: [ubuntu-20.04] env: DL_DIR: ../downloads BUILD_DIR: ../build @@ -30,7 +30,7 @@ jobs: echo "LIBUSB1_SRC=$PWD/libusb-${LIBUSB1_VER}" >> $GITHUB_ENV - name: Prepare hidapi env: - HIDAPI_VER: 0.11.2 + HIDAPI_VER: 0.13.1 run: | mkdir -p $DL_DIR && cd $DL_DIR wget "https://github.com/libusb/hidapi/archive/hidapi-${HIDAPI_VER}.tar.gz" @@ -82,6 +82,7 @@ jobs: # add missing dlls cd $HOST-root/usr cp `$HOST-gcc --print-file-name=libwinpthread-1.dll` ./bin/ + # required by libftdi1.dll. For the gcc-mingw-10.3.x or later "libgcc_s_dw2-1.dll" will need to be copied. cp `$HOST-gcc --print-file-name=libgcc_s_sjlj-1.dll` ./bin/ # prepare the artifact ARTIFACT="openocd-${OPENOCD_TAG}-${HOST}.tar.gz" @@ -90,11 +91,11 @@ jobs: echo "IS_PRE_RELEASE=$IS_PRE_RELEASE" >> $GITHUB_ENV echo "ARTIFACT_PATH=$PWD/$ARTIFACT" >> $GITHUB_ENV - name: Publish OpenOCD packaged for windows - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: path: ${{ env.ARTIFACT_PATH }} - name: Delete 'latest' Release - uses: dev-drprasad/delete-tag-and-release@v0.2.0 + uses: dev-drprasad/delete-tag-and-release@v0.2.1 with: delete_release: true tag_name: ${{ env.RELEASE_NAME }} From 99ec5760961d264599a9c9fb1a4d5d6042bc3ba8 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Sat, 25 Mar 2023 03:00:51 +0300 Subject: [PATCH 39/50] github/workflow: build libjaylink from source Libjaylink submodule disabled by default at https://review.openocd.org/c/openocd/+/7129 --enable-internal-libjaylink config option will be deprecated soon. So, building the source is a permanent solution. Signed-off-by: Erhan Kurubas Change-Id: Id06654d806a3a49f35e3ba41e9e4cc58c1a0d388 Reviewed-on: https://review.openocd.org/c/openocd/+/7552 Tested-by: jenkins Reviewed-by: zapb Reviewed-by: Antonio Borneo --- .github/workflows/snapshot.yml | 11 +++++++++++ contrib/cross-build.sh | 13 +++++++++++++ 2 files changed, 24 insertions(+) diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index b48388ef7c..f5cf56459c 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -56,6 +56,16 @@ jobs: wget "https://github.com/aquynh/capstone/archive/${CAPSTONE_VER}.tar.gz" tar -xzf ${CAPSTONE_VER}.tar.gz echo "CAPSTONE_SRC=$PWD/capstone-${CAPSTONE_VER}" >> $GITHUB_ENV + - name: Prepare libjaylink + env: + LIBJAYLINK_VER: 0.3.1 + run: | + mkdir -p $DL_DIR && cd $DL_DIR + wget https://gitlab.zapb.de/libjaylink/libjaylink/-/archive/${LIBJAYLINK_VER}/libjaylink-${LIBJAYLINK_VER}.tar.gz + tar -xzf libjaylink-${LIBJAYLINK_VER}.tar.gz + cd libjaylink-${LIBJAYLINK_VER} + ./autogen.sh + echo "LIBJAYLINK_SRC=$PWD" >> $GITHUB_ENV - name: Package OpenOCD for windows env: MAKE_JOBS: 2 @@ -64,6 +74,7 @@ jobs: HIDAPI_CONFIG: --enable-shared --disable-static --disable-testgui LIBFTDI_CONFIG: -DSTATICLIBS=OFF -DEXAMPLES=OFF -DFTDI_EEPROM=OFF CAPSTONE_CONFIG: "CAPSTONE_BUILD_CORE_ONLY=yes CAPSTONE_STATIC=yes CAPSTONE_SHARED=no" + LIBJAYLINK_CONFIG: --enable-shared --disable-static run: | # check if there is tag pointing at HEAD, otherwise take the HEAD SHA-1 as OPENOCD_TAG OPENOCD_TAG="`git tag --points-at HEAD`" diff --git a/contrib/cross-build.sh b/contrib/cross-build.sh index b199bf7157..bb8c8c47db 100755 --- a/contrib/cross-build.sh +++ b/contrib/cross-build.sh @@ -41,12 +41,14 @@ WORK_DIR=$PWD : ${HIDAPI_SRC:=/path/to/hidapi} : ${LIBFTDI_SRC:=/path/to/libftdi} : ${CAPSTONE_SRC:=/path/to/capstone} +: ${LIBJAYLINK_SRC:=/path/to/libjaylink} OPENOCD_SRC=`readlink -m $OPENOCD_SRC` LIBUSB1_SRC=`readlink -m $LIBUSB1_SRC` HIDAPI_SRC=`readlink -m $HIDAPI_SRC` LIBFTDI_SRC=`readlink -m $LIBFTDI_SRC` CAPSTONE_SRC=`readlink -m $CAPSTONE_SRC` +LIBJAYLINK_SRC=`readlink -m $LIBJAYLINK_SRC` HOST_TRIPLET=$1 BUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build @@ -54,6 +56,7 @@ LIBUSB1_BUILD_DIR=$BUILD_DIR/libusb1 HIDAPI_BUILD_DIR=$BUILD_DIR/hidapi LIBFTDI_BUILD_DIR=$BUILD_DIR/libftdi CAPSTONE_BUILD_DIR=$BUILD_DIR/capstone +LIBJAYLINK_BUILD_DIR=$BUILD_DIR/libjaylink OPENOCD_BUILD_DIR=$BUILD_DIR/openocd ## Root of host file tree @@ -158,6 +161,16 @@ libdir=${exec_prefix}/lib \ includedir=${prefix}/include/capstone\n\n;' $CAPSTONE_PC_FILE fi +# libjaylink build & install into sysroot +if [ -d $LIBJAYLINK_SRC ] ; then + mkdir -p $LIBJAYLINK_BUILD_DIR + cd $LIBJAYLINK_BUILD_DIR + $LIBJAYLINK_SRC/configure --build=`$LIBJAYLINK_SRC/config.guess` --host=$HOST_TRIPLET \ + --with-sysroot=$SYSROOT --prefix=$PREFIX \ + $LIBJAYLINK_CONFIG + make -j $MAKE_JOBS + make install DESTDIR=$SYSROOT +fi # OpenOCD build & install into sysroot mkdir -p $OPENOCD_BUILD_DIR From 41037eb26585114209c3c8f1d63f7788a421df07 Mon Sep 17 00:00:00 2001 From: Chao Du Date: Wed, 22 Mar 2023 06:51:51 +0000 Subject: [PATCH 40/50] rtos/FreeRTOS: some optimization of freertos_update_threads() 1. update the rtos->thread_count in time, to make sure the allocated thread_name_str and extra_info_str could be freed by rtos_free_threadlist(). Otherwise the abnormal return may cause a memory leak. 2. remove a redundant assignment to threadid. Signed-off-by: Chao Du Change-Id: Ifabc59d501c925b3d6aec8b04b2856d2c31cc4e2 Reviewed-on: https://review.openocd.org/c/openocd/+/7549 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Antonio Borneo --- src/rtos/FreeRTOS.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index 070275f2c5..e8df030aad 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -312,7 +312,6 @@ static int freertos_update_threads(struct rtos *rtos) (list_elem_ptr != prev_list_elem_ptr) && (tasks_found < thread_list_size)) { /* Get the location of the thread structure. */ - rtos->thread_details[tasks_found].threadid = 0; retval = target_read_u32(rtos->target, list_elem_ptr + param->list_elem_content_offset, &pointer_casts_are_bad); @@ -365,6 +364,7 @@ static int freertos_update_threads(struct rtos *rtos) tasks_found++; list_thread_count--; + rtos->thread_count = tasks_found; prev_list_elem_ptr = list_elem_ptr; list_elem_ptr = 0; @@ -383,7 +383,6 @@ static int freertos_update_threads(struct rtos *rtos) } free(list_of_lists); - rtos->thread_count = tasks_found; return 0; } From 18aacc8bf3ff7c7481673cbbfe82f0104e4dccf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20LEGAL?= Date: Wed, 29 Mar 2023 14:19:48 +0200 Subject: [PATCH 41/50] src/target/mips_m4k : fix condition on overlapping workspace data area MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The condition to check if the workspace area (used by actual MIPS code executed on target) and data area (sandbox to put data to be read/written to/from flash) is wrong, thus preventing the use of FAST_* commands to program/verify FLASH. Signed-off-by: François LEGAL Change-Id: Ic68424b7f42d44e550433a120093db5e7980fd56 Reviewed-on: https://review.openocd.org/c/openocd/+/7563 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/mips_m4k.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 491b247b15..d3b07585dd 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -1218,8 +1218,8 @@ static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t addre fast_data_area = mips32->fast_data_area; - if (address <= fast_data_area->address + fast_data_area->size && - fast_data_area->address <= address + count) { + if (address < (fast_data_area->address + fast_data_area->size) && + fast_data_area->address < (address + count)) { LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area " "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").", fast_data_area->address, address, address + count); From 55e04e3157cd4d817cfd39c6f1384f96d61a0951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20LEGAL?= Date: Wed, 29 Mar 2023 17:46:38 +0200 Subject: [PATCH 42/50] src/target/mips_m4k : add fast read method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the fast read method to speed up flash verification after programming. Works the same as fast write already implemented. Signed-off-by: François LEGAL Change-Id: I74611a3542a88212f0483ec8ee368aba3d1f03c7 Reviewed-on: https://review.openocd.org/c/openocd/+/7564 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/mips_m4k.c | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index d3b07585dd..14e3f3b27a 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -36,6 +36,8 @@ static int mips_m4k_internal_restore(struct target *target, int current, static int mips_m4k_halt(struct target *target); static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer); +static int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address, + uint32_t count, uint8_t *buffer); static int mips_m4k_examine_debug_reason(struct target *target) { @@ -1021,6 +1023,12 @@ static int mips_m4k_read_memory(struct target *target, target_addr_t address, if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) return ERROR_TARGET_UNALIGNED_ACCESS; + if (size == 4 && count > 32) { + int retval = mips_m4k_bulk_read_memory(target, address, count, buffer); + if (retval == ERROR_OK) + return ERROR_OK; + LOG_WARNING("Falling back to non-bulk read"); + } /* since we don't know if buffer is aligned, we allocate new mem that is always aligned */ void *t = NULL; @@ -1249,6 +1257,71 @@ static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t addre return retval; } +static int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address, + uint32_t count, uint8_t *buffer) +{ + struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; + struct working_area *fast_data_area; + int retval; + int write_t = 0; + + LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "", + address, count); + + /* check alignment */ + if (address & 0x3u) + return ERROR_TARGET_UNALIGNED_ACCESS; + + if (!mips32->fast_data_area) { + /* Get memory for block read handler + * we preserve this area between calls and gain a speed increase + * of about 3kb/sec when reading flash + * this will be released/nulled by the system when the target is resumed or reset */ + retval = target_alloc_working_area(target, + MIPS32_FASTDATA_HANDLER_SIZE, + &mips32->fast_data_area); + if (retval != ERROR_OK) { + LOG_ERROR("No working area available"); + return retval; + } + + /* reset fastadata state so the algo get reloaded */ + ejtag_info->fast_access_save = -1; + } + + fast_data_area = mips32->fast_data_area; + + if (address < (fast_data_area->address + fast_data_area->size) && + fast_data_area->address < (address + count)) { + LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within read area " + "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").", + fast_data_area->address, address, address + count); + LOG_ERROR("Change work-area-phys or load_image address!"); + return ERROR_FAIL; + } + + /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */ + /* but byte array represents target endianness */ + uint32_t *t = malloc(count * sizeof(uint32_t)); + if (!t) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address, + count, t); + + target_buffer_set_u32_array(target, buffer, count, t); + + free(t); + + if (retval != ERROR_OK) + LOG_ERROR("Fastdata access Failed"); + + return retval; +} + static int mips_m4k_verify_pointer(struct command_invocation *cmd, struct mips_m4k_common *mips_m4k) { From 90ce9da644d751466d8dc451d7d2a043cdbf7d72 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 Mar 2023 15:01:18 +0100 Subject: [PATCH 43/50] helper/list: remove unused hlist_* The file list.h is taken from Linux and includes two similar implementation of double linked lists: - with single linked list's head (hlist_*), and - with double linked list's head (list_*). While the former offers a minor memory footprint improvement, keeping two implementations makes harder for newbie developers to approach them. So far only the latter implementation has been used and no new patches in gerrit is going to change that. Drop the support for lists with single linked head. It can be easily taken back from git history, if needed. Change-Id: I420e5de38ab755fdfbeb2115538c61818308ec2b Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7567 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/helper/list.h | 239 +--------------------------------------------- 1 file changed, 1 insertion(+), 238 deletions(-) diff --git a/src/helper/list.h b/src/helper/list.h index 552a3202a5..396ff06c9e 100644 --- a/src/helper/list.h +++ b/src/helper/list.h @@ -27,13 +27,6 @@ struct list_head { struct list_head *next, *prev; }; -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; /* end local changes */ /* @@ -811,237 +804,7 @@ static inline void list_splice_tail_init(struct list_head *list, /* * Double linked lists with a single pointer list head. - * Mostly useful for hash tables where the two pointer list head is - * too wasteful. - * You lose the ability to access the tail in O(1). - */ - -#define HLIST_HEAD_INIT { .first = NULL } -#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } -#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) -static inline void INIT_HLIST_NODE(struct hlist_node *h) -{ - h->next = NULL; - h->pprev = NULL; -} - -/** - * hlist_unhashed - Has node been removed from list and reinitialized? - * @param h Node to be checked - * - * Not that not all removal functions will leave a node in unhashed - * state. For example, hlist_nulls_del_init_rcu() does leave the - * node in unhashed state, but hlist_nulls_del() does not. - */ -static inline int hlist_unhashed(const struct hlist_node *h) -{ - return !h->pprev; -} - -/* Ignore kernel hlist_unhashed_lockless() */ - -/** - * hlist_empty - Is the specified hlist_head structure an empty hlist? - * @param h Structure to check. - */ -static inline int hlist_empty(const struct hlist_head *h) -{ - return !h->first; -} - -static inline void __hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - - *pprev = next; - if (next) - next->pprev = pprev; -} - -/** - * hlist_del - Delete the specified hlist_node from its list - * @param n Node to delete. - * - * Note that this function leaves the node in hashed state. Use - * hlist_del_init() or similar instead to unhash @a n. - */ -static inline void hlist_del(struct hlist_node *n) -{ - __hlist_del(n); - n->next = LIST_POISON1; - n->pprev = LIST_POISON2; -} - -/** - * hlist_del_init - Delete the specified hlist_node from its list and initialize - * @param n Node to delete. - * - * Note that this function leaves the node in unhashed state. - */ -static inline void hlist_del_init(struct hlist_node *n) -{ - if (!hlist_unhashed(n)) { - __hlist_del(n); - INIT_HLIST_NODE(n); - } -} - -/** - * hlist_add_head - add a new entry at the beginning of the hlist - * @param n new entry to be added - * @param h hlist head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - if (first) - first->pprev = &n->next; - h->first = n; - n->pprev = &h->first; -} - -/** - * hlist_add_before - add a new entry before the one specified - * @param n new entry to be added - * @param next hlist node to add it before, which must be non-NULL - */ -static inline void hlist_add_before(struct hlist_node *n, - struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; - next->pprev = &n->next; - *(n->pprev) = n; -} - -/** - * hlist_add_behind - add a new entry after the one specified - * @param n new entry to be added - * @param prev hlist node to add it after, which must be non-NULL - */ -static inline void hlist_add_behind(struct hlist_node *n, - struct hlist_node *prev) -{ - n->next = prev->next; - prev->next = n; - n->pprev = &prev->next; - - if (n->next) - n->next->pprev = &n->next; -} - -/** - * hlist_add_fake - create a fake hlist consisting of a single headless node - * @param n Node to make a fake list out of - * - * This makes @a n appear to be its own predecessor on a headless hlist. - * The point of this is to allow things like hlist_del() to work correctly - * in cases where there is no list. - */ -static inline void hlist_add_fake(struct hlist_node *n) -{ - n->pprev = &n->next; -} - -/** - * hlist_fake: Is this node a fake hlist? - * @param h Node to check for being a self-referential fake hlist. - */ -static inline bool hlist_fake(struct hlist_node *h) -{ - return h->pprev == &h->next; -} - -/** - * hlist_is_singular_node - is node the only element of the specified hlist? - * @param n Node to check for singularity. - * @param h Header for potentially singular list. - * - * Check whether the node is the only node of the head without - * accessing head, thus avoiding unnecessary cache misses. - */ -static inline bool -hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h) -{ - return !n->next && n->pprev == &h->first; -} - -/** - * hlist_move_list - Move an hlist - * @param old hlist_head for old list. - * @param new hlist_head for new list. - * - * Move a list from one list head to another. Fixup the pprev - * reference of the first entry if it exists. - */ -static inline void hlist_move_list(struct hlist_head *old, - struct hlist_head *new) -{ - new->first = old->first; - if (new->first) - new->first->pprev = &new->first; - old->first = NULL; -} - -#define hlist_entry(ptr, type, member) container_of(ptr, type, member) - -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos ; pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ - pos = n) - -#define hlist_entry_safe(ptr, type, member) \ - ({ typeof(ptr) ____ptr = (ptr); \ - ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ - }) - -/** - * hlist_for_each_entry - iterate over list of given type - * @param pos the type * to use as a loop cursor. - * @param head the head for your list. - * @param member the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry(pos, head, member) \ - for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ - pos; \ - pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) - -/** - * hlist_for_each_entry_continue - iterate over a hlist continuing after current point - * @param pos the type * to use as a loop cursor. - * @param member the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_continue(pos, member) \ - for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\ - pos; \ - pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) - -/** - * hlist_for_each_entry_from - iterate over a hlist continuing from current point - * @param pos the type * to use as a loop cursor. - * @param member the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_from(pos, member) \ - for (; pos; \ - pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) - -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @param pos the type * to use as a loop cursor. - * @param n a &struct hlist_node to use as temporary storage - * @param head the head for your list. - * @param member the name of the hlist_node within the struct. + * IGNORED */ -#define hlist_for_each_entry_safe(pos, n, head, member) \ - for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ - pos && ({ n = pos->member.next; 1; }); \ - pos = hlist_entry_safe(n, typeof(*pos), member)) #endif /* OPENOCD_HELPER_LIST_H */ From c8de1b82ec7f74c0717bfa0094f5fb6b79fbbfaf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 Mar 2023 15:20:14 +0100 Subject: [PATCH 44/50] helper/list: re-align with Linux kernel 6.3-rc1 Minor changes due to kernel switch to 100 char/line. Added four new functions. Silent checkpatch; we don't want to diverge from Linux reference code. Checkpatch-ignore: MACRO_ARG_REUSE, UNNECESSARY_PARENTHESES Checkpatch-ignore: MACRO_ARG_PRECEDENCE Change-Id: I1d2ff25bf3bab8cd0f5c9be55c7501795490ea75 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/7568 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/helper/list.h | 66 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/src/helper/list.h b/src/helper/list.h index 396ff06c9e..c9de0569bc 100644 --- a/src/helper/list.h +++ b/src/helper/list.h @@ -265,8 +265,7 @@ static inline void list_bulk_move_tail(struct list_head *head, * @param list the entry to test * @param head the head of the list */ -static inline int list_is_first(const struct list_head *list, - const struct list_head *head) +static inline int list_is_first(const struct list_head *list, const struct list_head *head) { return list->prev == head; } @@ -276,12 +275,21 @@ static inline int list_is_first(const struct list_head *list, * @param list the entry to test * @param head the head of the list */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) +static inline int list_is_last(const struct list_head *list, const struct list_head *head) { return list->next == head; } +/** + * list_is_head - tests whether @a list is the list @a head + * @param list the entry to test + * @param head the head of the list + */ +static inline int list_is_head(const struct list_head *list, const struct list_head *head) +{ + return list == head; +} + /** * list_empty - tests whether a list is empty * @param head the list to test. @@ -400,10 +408,9 @@ static inline void list_cut_position(struct list_head *list, { if (list_empty(head)) return; - if (list_is_singular(head) && - (head->next != entry && head != entry)) + if (list_is_singular(head) && !list_is_head(entry, head) && (entry != head->next)) return; - if (entry == head) + if (list_is_head(entry, head)) INIT_LIST_HEAD(list); else __list_cut_position(list, head, entry); @@ -563,6 +570,19 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_next_entry(pos, member) \ list_entry((pos)->member.next, typeof(*(pos)), member) +/** + * list_next_entry_circular - get the next element in list + * @param pos the type * to cursor. + * @param head the list head to take the element from. + * @param member the name of the list_head within the struct. + * + * Wraparound if pos is the last element (return the first element). + * Note, that list is expected to be not empty. + */ +#define list_next_entry_circular(pos, head, member) \ + (list_is_last(&(pos)->member, head) ? \ + list_first_entry(head, typeof(*(pos)), member) : list_next_entry(pos, member)) + /** * list_prev_entry - get the prev element in list * @param pos the type * to cursor @@ -571,13 +591,28 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_prev_entry(pos, member) \ list_entry((pos)->member.prev, typeof(*(pos)), member) +/** + * list_prev_entry_circular - get the prev element in list + * @param pos the type * to cursor. + * @param head the list head to take the element from. + * @param member the name of the list_head within the struct. + * + * Wraparound if pos is the first element (return the last element). + * Note, that list is expected to be not empty. + */ +#define list_prev_entry_circular(pos, head, member) \ + (list_is_first(&(pos)->member, head) ? \ + list_last_entry(head, typeof(*(pos)), member) : list_prev_entry(pos, member)) + /** * list_for_each - iterate over a list * @param pos the &struct list_head to use as a loop cursor. * @param head the head for your list. */ #define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) + for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) + +/* Ignore kernel list_for_each_rcu() */ /** * list_for_each_continue - continue iteration over a list @@ -618,6 +653,21 @@ static inline void list_splice_tail_init(struct list_head *list, pos != (head); \ pos = n, n = pos->prev) +/** + * list_count_nodes - count nodes in the list + * @param head the head for your list. + */ +static inline size_t list_count_nodes(struct list_head *head) +{ + struct list_head *pos; + size_t count = 0; + + list_for_each(pos, head) + count++; + + return count; +} + /** * list_entry_is_head - test if the entry points to the head of the list * @param pos the type * to cursor From 7e0797d19ac1837e3001df9d45030b5eb97ca36d Mon Sep 17 00:00:00 2001 From: Daniel Anselmi Date: Wed, 14 Dec 2022 12:51:48 +0100 Subject: [PATCH 45/50] ipdbg: whitespaces Change-Id: I9294c551cf2e795ad5e3e92dc3926c564424e067 Signed-off-by: Daniel Anselmi Reviewed-on: https://review.openocd.org/c/openocd/+/7399 Tested-by: jenkins Reviewed-by: Jonathan McDowell Reviewed-by: Antonio Borneo --- src/server/ipdbg.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c index f4a6f6cdcc..755d0510ed 100644 --- a/src/server/ipdbg.c +++ b/src/server/ipdbg.c @@ -90,7 +90,7 @@ static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo) return; size_t ri = fifo->rd_idx; - for (size_t idx = 0 ; idx < fifo->count ; ++idx) + for (size_t idx = 0; idx < fifo->count; ++idx) fifo->buffer[idx] = fifo->buffer[ri++]; fifo->rd_idx = 0; } @@ -149,7 +149,7 @@ static int ipdbg_max_tools_from_data_register_length(uint8_t data_register_lengt static struct ipdbg_service *ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool) { struct ipdbg_service *service; - for (service = ipdbg_first_service ; service ; service = service->next) { + for (service = ipdbg_first_service; service; service = service->next) { if (service->hub == hub && service->tool == tool) break; } @@ -160,7 +160,7 @@ static void ipdbg_add_service(struct ipdbg_service *service) { struct ipdbg_service *iservice; if (ipdbg_first_service) { - for (iservice = ipdbg_first_service ; iservice->next; iservice = iservice->next) + for (iservice = ipdbg_first_service; iservice->next; iservice = iservice->next) ; iservice->next = service; } else @@ -192,7 +192,7 @@ static int ipdbg_remove_service(struct ipdbg_service *service) return ERROR_OK; } - for (struct ipdbg_service *iservice = ipdbg_first_service ; iservice->next ; iservice = iservice->next) { + for (struct ipdbg_service *iservice = ipdbg_first_service; iservice->next; iservice = iservice->next) { if (service == iservice->next) { iservice->next = service->next; return ERROR_OK; @@ -205,7 +205,7 @@ static struct ipdbg_hub *ipdbg_find_hub(struct jtag_tap *tap, uint32_t user_instruction, struct ipdbg_virtual_ir_info *virtual_ir) { struct ipdbg_hub *hub = NULL; - for (hub = ipdbg_first_hub ; hub ; hub = hub->next) { + for (hub = ipdbg_first_hub; hub; hub = hub->next) { if (hub->tap == tap && hub->user_instruction == user_instruction) { if ((!virtual_ir && !hub->virtual_ir) || (virtual_ir && hub->virtual_ir && @@ -223,7 +223,7 @@ static void ipdbg_add_hub(struct ipdbg_hub *hub) { struct ipdbg_hub *ihub; if (ipdbg_first_hub) { - for (ihub = ipdbg_first_hub ; ihub->next; ihub = ihub->next) + for (ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next) ; ihub->next = hub; } else @@ -281,7 +281,7 @@ static int ipdbg_remove_hub(struct ipdbg_hub *hub) return ERROR_OK; } - for (struct ipdbg_hub *ihub = ipdbg_first_hub ; ihub->next ; ihub = ihub->next) { + for (struct ipdbg_hub *ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next) { if (hub == ihub->next) { ihub->next = hub->next; return ERROR_OK; @@ -447,7 +447,7 @@ static int ipdbg_polling_callback(void *priv) /* transfer dn buffers to jtag-hub */ unsigned int num_transfers = 0; - for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) { + for (size_t tool = 0; tool < hub->max_tools; ++tool) { struct connection *conn = hub->connections[tool]; if (conn && conn->priv) { struct ipdbg_connection *connection = conn->priv; @@ -475,7 +475,7 @@ static int ipdbg_polling_callback(void *priv) } /* write from up fifos to sockets */ - for (size_t tool = 0 ; tool < hub->max_tools ; ++tool) { + for (size_t tool = 0; tool < hub->max_tools; ++tool) { struct connection *conn = hub->connections[tool]; if (conn && conn->priv) { struct ipdbg_connection *connection = conn->priv; From 561f27fde9dc51f014b672c227dc7c8ca2530fcf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 2 Apr 2023 14:24:23 +0200 Subject: [PATCH 46/50] helper/compiler fix build with gcc on MacOS On MacOS libc includes files from MacOSX.sdk that define the macro #define __nonnull without arguments, causing compile error. Extend the existing check for clang on MacOS and undefine the macro for gcc too. Change-Id: Ic99de78348c6aa86561212a3aded9342e5d32e02 Signed-off-by: Antonio Borneo Reported-by: Erhan Kurubas Reviewed-on: https://review.openocd.org/c/openocd/+/7571 Reviewed-by: Erhan Kurubas Tested-by: jenkins --- src/helper/compiler.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/helper/compiler.h b/src/helper/compiler.h index 33a075d64f..312d261fc3 100644 --- a/src/helper/compiler.h +++ b/src/helper/compiler.h @@ -36,9 +36,11 @@ * clang for Apple defines * #define __nonnull _Nonnull * that is a per argument attribute, incompatible with the gcc per function attribute __nonnull__. - * Undefine it to keep compatibility among compilers. + * gcc for Apple includes sys/cdefs.h from MacOSX.sdk that defines + * #define __nonnull + * In both cases, undefine __nonnull to keep compatibility among compilers and platforms. */ -#if defined(__clang__) && defined(__APPLE__) +#if defined(__APPLE__) # undef __nonnull #endif #ifndef __nonnull From e87fa5e3ab424d3ccd66eeddccfbe1e0181e20d0 Mon Sep 17 00:00:00 2001 From: Daniel Anselmi Date: Wed, 30 Nov 2022 03:42:18 +0100 Subject: [PATCH 47/50] tcl: zynq_7000: add missing id codes Add missing ID codes and ignore the version in the ID. Change-Id: Idd2d3a5eddb6995f3af1c45afd2adf76ce3442bf Signed-off-by: Daniel Anselmi Reviewed-on: https://review.openocd.org/c/openocd/+/7386 Tested-by: jenkins Reviewed-by: Tomas Vanek --- tcl/target/zynq_7000.cfg | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/tcl/target/zynq_7000.cfg b/tcl/target/zynq_7000.cfg index 0272587c1e..a6f8995417 100644 --- a/tcl/target/zynq_7000.cfg +++ b/tcl/target/zynq_7000.cfg @@ -1,18 +1,34 @@ # SPDX-License-Identifier: GPL-2.0-or-later -# # Xilinx Zynq-7000 All Programmable SoC # # http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm +# https://www.xilinx.com/member/forms/download/sim-model-eval-license-xef.html?filename=bsdl_zynq_2.zip # +# 0x03736093 XQ7Z100 XC7Z100I XC7Z100 +# 0x03731093 XQ7Z045 XC7Z045I XC7Z045 +# 0x0372c093 XQ7Z030 XC7Z030I XC7Z030 XA7Z030 +# 0x03727093 XQ7Z020 XC7Z020I XC7Z020 XA7Z020 +# 0x03732093 XC7Z035I XC7Z035 +# 0x0373b093 XC7Z015I XC7Z015 +# 0x03728093 XC7Z014S +# 0x0373c093 XC7Z012S +# 0x03722093 XC7Z010I XC7Z010 XA7Z010 +# 0x03723093 XC7Z007S set _CHIPNAME zynq set _TARGETNAME $_CHIPNAME.cpu -jtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \ - -expected-id 0x23727093 \ - -expected-id 0x13722093 \ +jtag newtap zynq_pl bs -irlen 6 -ignore-version -ircapture 0x1 -irmask 0x03 \ + -expected-id 0x03723093 \ + -expected-id 0x03722093 \ + -expected-id 0x0373c093 \ + -expected-id 0x03728093 \ + -expected-id 0x0373B093 \ + -expected-id 0x03732093 \ -expected-id 0x03727093 \ + -expected-id 0x0372C093 \ + -expected-id 0x03731093 \ -expected-id 0x03736093 jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477 From ffd9638bdb04fb3021a20f78330c4692a2ebab6a Mon Sep 17 00:00:00 2001 From: Daniel Anselmi Date: Wed, 30 Nov 2022 04:05:44 +0100 Subject: [PATCH 48/50] tcl: cpld/xilinx-xc7: remove virtex-7 devices with ir-length > 6 They have an ir length of 22, 24 or 38 bit and different command codes. Change-Id: I488e8613f1c4d017e1590111f60b2725ec62964b Signed-off-by: Daniel Anselmi Reviewed-on: https://review.openocd.org/c/openocd/+/7387 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/cpld/xilinx-xc7.cfg | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tcl/cpld/xilinx-xc7.cfg b/tcl/cpld/xilinx-xc7.cfg index 22e0aea7f9..91a07f9eb4 100644 --- a/tcl/cpld/xilinx-xc7.cfg +++ b/tcl/cpld/xilinx-xc7.cfg @@ -33,19 +33,21 @@ jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \ -expected-id 0x03752093 \ -expected-id 0x03751093 \ -expected-id 0x03671093 \ - -expected-id 0x036B3093 \ - -expected-id 0x036B7093 \ - -expected-id 0x036BB093 \ - -expected-id 0x036BF093 \ -expected-id 0x03667093 \ -expected-id 0x03682093 \ -expected-id 0x03687093 \ -expected-id 0x03692093 \ -expected-id 0x03691093 \ - -expected-id 0x03696093 \ - -expected-id 0x036D5093 \ - -expected-id 0x036D9093 \ - -expected-id 0x036DB093 + -expected-id 0x03696093 + +#jtag newtap $_CHIPNAME tap -irlen 24 -ignore-version \ +# -expected-id 0x036B3093 -expected-id 0x036B7093 \ +# -expected-id 0x036BB093 -expected-id 0x036BF093 \ +# -expected-id 0x036D5093 + +#jtag newtap $_CHIPNAME tap -irlen 22 -ignore-version -expected-id 0x036D9093 + +#jtag newtap $_CHIPNAME tap -irlen 38 -ignore-version -expected-id 0x036DB093 pld device virtex2 $_CHIPNAME.tap 1 From 0384fe5d596f42388f8b84d42959d899f29388ab Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 4 Apr 2023 13:03:59 +0200 Subject: [PATCH 49/50] doc: drop "resume will wait 5 seconds" Checkpatch-ignore: GIT_COMMIT_ID Waiting for running state was removed from handle_resume_command() in commit a92d27afb073 ("very long and bad structured commit msg without anything relevant to resume") around year 2008. Update the doc accordingly. Silent checkpatch or we have to copy 10 or more lines of the old commit msg. Signed-off-by: Tomas Vanek Change-Id: I3296cb2c29cf80aeed63eddd8fbf352edec778c1 Reviewed-on: https://review.openocd.org/c/openocd/+/7579 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 67661845d0..fe72cf5fac 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -8780,7 +8780,6 @@ power consumption (because the CPU is needlessly clocked). @deffn {Command} {resume} [address] Resume the target at its current code position, or the optional @var{address} if it is provided. -OpenOCD will wait 5 seconds for the target to resume. @end deffn @deffn {Command} {step} [address] From d6060b5d55c8f8082e17d054732f3eb642b6a51a Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 16 Oct 2023 12:52:24 -0700 Subject: [PATCH 50/50] Copy snapshot.yml from upstream At change 0384fe5. Change-Id: I1081e09f1014c5d240988fc25feba04fc2bb21ef Signed-off-by: Tim Newsome --- .github/workflows/snapshot.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 71bfecc80d..f5cf56459c 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -2,7 +2,7 @@ # Copyright (C) 2020 by Tarek BOUCHKATI -on: pull_request +on: push name: OpenOCD Snapshot @@ -74,7 +74,6 @@ jobs: HIDAPI_CONFIG: --enable-shared --disable-static --disable-testgui LIBFTDI_CONFIG: -DSTATICLIBS=OFF -DEXAMPLES=OFF -DFTDI_EEPROM=OFF CAPSTONE_CONFIG: "CAPSTONE_BUILD_CORE_ONLY=yes CAPSTONE_STATIC=yes CAPSTONE_SHARED=no" - CAPSTONE_CFLAGS: -I$(CAPSTONE_SRC)/include/capstone LIBJAYLINK_CONFIG: --enable-shared --disable-static run: | # check if there is tag pointing at HEAD, otherwise take the HEAD SHA-1 as OPENOCD_TAG @@ -102,11 +101,9 @@ jobs: echo "RELEASE_NAME=$RELEASE_NAME" >> $GITHUB_ENV echo "IS_PRE_RELEASE=$IS_PRE_RELEASE" >> $GITHUB_ENV echo "ARTIFACT_PATH=$PWD/$ARTIFACT" >> $GITHUB_ENV - echo "ARTIFACT_NAME=openocd-windows-${OPENOCD_TAG}" >> $GITHUB_ENV - name: Publish OpenOCD packaged for windows uses: actions/upload-artifact@v3 with: - name: ${{ env.ARTIFACT_NAME }} path: ${{ env.ARTIFACT_PATH }} - name: Delete 'latest' Release uses: dev-drprasad/delete-tag-and-release@v0.2.1