diff options
Diffstat (limited to 'src')
100 files changed, 3922 insertions, 1145 deletions
diff --git a/src/flash/nand/core.h b/src/flash/nand/core.h index 5bf9fb3..12fc2b7 100644 --- a/src/flash/nand/core.h +++ b/src/flash/nand/core.h @@ -100,7 +100,7 @@ struct nand_info { const char *name; }; -/* Option constants for bizarre disfunctionality and real features +/* Option constants for bizarre dysfunctionality and real features */ enum { /* Chip can not auto increment pages */ diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c index 97bd7a3..6ce0575 100644 --- a/src/flash/nand/lpc3180.c +++ b/src/flash/nand/lpc3180.c @@ -139,9 +139,9 @@ static int lpc3180_init(struct nand_device *nand) { struct lpc3180_nand_controller *lpc3180_info = nand->controller_priv; struct target *target = nand->target; - int bus_width = nand->bus_width ? : 8; - int address_cycles = nand->address_cycles ? : 3; - int page_size = nand->page_size ? : 512; + int bus_width = nand->bus_width ? nand->bus_width : 8; + int address_cycles = nand->address_cycles ? nand->address_cycles : 3; + int page_size = nand->page_size ? nand->page_size : 512; if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use LPC3180 NAND flash controller"); diff --git a/src/flash/nand/lpc32xx.c b/src/flash/nand/lpc32xx.c index 6443beb..f117ead 100644 --- a/src/flash/nand/lpc32xx.c +++ b/src/flash/nand/lpc32xx.c @@ -191,9 +191,9 @@ static int lpc32xx_init(struct nand_device *nand) { struct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv; struct target *target = nand->target; - int bus_width = nand->bus_width ? : 8; - int address_cycles = nand->address_cycles ? : 3; - int page_size = nand->page_size ? : 512; + int bus_width = nand->bus_width ? nand->bus_width : 8; + int address_cycles = nand->address_cycles ? nand->address_cycles : 3; + int page_size = nand->page_size ? nand->page_size : 512; int retval; if (target->state != TARGET_HALTED) { diff --git a/src/flash/nand/nuc910.c b/src/flash/nand/nuc910.c index 1a2dd59..9546f2f 100644 --- a/src/flash/nand/nuc910.c +++ b/src/flash/nand/nuc910.c @@ -183,7 +183,7 @@ static int nuc910_nand_init(struct nand_device *nand) { struct nuc910_nand_controller *nuc910_nand = nand->controller_priv; struct target *target = nand->target; - int bus_width = nand->bus_width ? : 8; + int bus_width = nand->bus_width ? nand->bus_width : 8; int result; result = validate_target_state(nand); diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index e6b452e..1fee6eb 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -2803,7 +2803,7 @@ static int kinetis_blank_check(struct flash_bank *bank) struct kinetis_chip *k_chip = k_bank->k_chip; int result; - /* suprisingly blank check does not work in VLPR and HSRUN modes */ + /* surprisingly blank check does not work in VLPR and HSRUN modes */ result = kinetis_check_run_mode(k_chip); if (result != ERROR_OK) return result; diff --git a/src/flash/nor/mrvlqspi.c b/src/flash/nor/mrvlqspi.c index 3f5ce2c..b98c49d 100644 --- a/src/flash/nor/mrvlqspi.c +++ b/src/flash/nor/mrvlqspi.c @@ -37,7 +37,7 @@ #define QSPI_W_EN (0x1) #define QSPI_SS_DISABLE (0x0) #define QSPI_SS_ENABLE (0x1) -#define WRITE_DISBALE (0x0) +#define WRITE_DISABLE (0x0) #define WRITE_ENABLE (0x1) #define QSPI_TIMEOUT (1000) diff --git a/src/flash/nor/msp432.h b/src/flash/nor/msp432.h index 663393b..af1d40c 100644 --- a/src/flash/nor/msp432.h +++ b/src/flash/nor/msp432.h @@ -43,7 +43,7 @@ #define P4_SECTOR_LENGTH 0x1000 #define P4_ALGO_ENTRY_ADDR 0x01000110 -/* MSP432E4 flash paramters */ +/* MSP432E4 flash parameters */ #define E4_FLASH_BASE FLASH_BASE #define E4_FLASH_SIZE 0x100000 #define E4_SECTOR_LENGTH 0x4000 diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index b9d567e..de799fa 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -1037,7 +1037,7 @@ static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer, * RM reads: Code running from code region 1 will not be able to write * to code region 0. * Unfortunately the flash loader running from RAM can write to both - * code regions whithout any hint the protection is violated. + * code regions without any hint the protection is violated. * * Update protection state and check if any flash sector to be written * is protected. */ diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c index b606e18..3ca1f36 100644 --- a/src/flash/nor/psoc4.c +++ b/src/flash/nor/psoc4.c @@ -335,7 +335,7 @@ static int psoc4_sysreq(struct flash_bank *bank, uint8_t cmd, /* Execute wait code */ retval = target_run_algorithm(target, 0, NULL, - sizeof(reg_params) / sizeof(*reg_params), reg_params, + ARRAY_SIZE(reg_params), reg_params, sysreq_wait_algorithm->address, 0, 1000, &armv7m_info); if (retval != ERROR_OK) { LOG_ERROR("sysreq wait code execution failed"); diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 594bce0..7e1fe7c 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -1351,8 +1351,10 @@ static int stm32l4_probe(struct flash_bank *bank) device_id = stm32l4_info->idcode & 0xFFF; for (unsigned int n = 0; n < ARRAY_SIZE(stm32l4_parts); n++) { - if (device_id == stm32l4_parts[n].id) + if (device_id == stm32l4_parts[n].id) { stm32l4_info->part_info = &stm32l4_parts[n]; + break; + } } if (!stm32l4_info->part_info) { diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c index 3cb1a49..b014d09 100644 --- a/src/flash/nor/stm32lx.c +++ b/src/flash/nor/stm32lx.c @@ -533,8 +533,8 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff buf_set_u32(reg_params[2].value, 0, 32, this_count / 4); /* 5: Execute the bunch of code */ - retval = target_run_algorithm(target, 0, NULL, sizeof(reg_params) - / sizeof(*reg_params), reg_params, + retval = target_run_algorithm(target, 0, NULL, + ARRAY_SIZE(reg_params), reg_params, write_algorithm->address, 0, 10000, &armv7m_info); if (retval != ERROR_OK) break; diff --git a/src/flash/nor/stmqspi.c b/src/flash/nor/stmqspi.c index 11aa438..a3555a4 100644 --- a/src/flash/nor/stmqspi.c +++ b/src/flash/nor/stmqspi.c @@ -175,7 +175,7 @@ struct stmqspi_flash_bank { bool octo; struct flash_device dev; uint32_t io_base; - uint32_t saved_cr; /* in particalar FSEL, DFM bit mask in QUADSPI_CR *AND* OCTOSPI_CR */ + uint32_t saved_cr; /* in particular FSEL, DFM bit mask in QUADSPI_CR *AND* OCTOSPI_CR */ uint32_t saved_ccr; /* different meaning for QUADSPI and OCTOSPI */ uint32_t saved_tcr; /* only for OCTOSPI */ uint32_t saved_ir; /* only for OCTOSPI */ diff --git a/src/flash/nor/xcf.c b/src/flash/nor/xcf.c index 0cef43b..01329f4 100644 --- a/src/flash/nor/xcf.c +++ b/src/flash/nor/xcf.c @@ -169,7 +169,7 @@ static int isc_enter(struct flash_bank *bank) jtag_execute_queue(); status = read_status(bank); - if (false == status.isc_mode) { + if (!status.isc_mode) { LOG_ERROR("*** XCF: FAILED to enter ISC mode"); return ERROR_FLASH_OPERATION_FAILED; } @@ -183,7 +183,7 @@ static int isc_leave(struct flash_bank *bank) struct xcf_status status = read_status(bank); - if (false == status.isc_mode) + if (!status.isc_mode) return ERROR_OK; else { struct scan_field scan; @@ -199,7 +199,7 @@ static int isc_leave(struct flash_bank *bank) alive_sleep(1); /* device needs 50 uS to leave ISC mode */ status = read_status(bank); - if (true == status.isc_mode) { + if (status.isc_mode) { LOG_ERROR("*** XCF: FAILED to leave ISC mode"); return ERROR_FLASH_OPERATION_FAILED; } @@ -280,7 +280,7 @@ static int isc_set_register(struct flash_bank *bank, const uint8_t *cmd, scan.in_value = NULL; jtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE); - if (0 == timeout_ms) + if (timeout_ms == 0) return jtag_execute_queue(); else return isc_wait_erase_program(bank, timeout_ms); @@ -311,7 +311,7 @@ static int isc_program_register(struct flash_bank *bank, const uint8_t *cmd, scan.in_value = NULL; jtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE); - if (0 == timeout_ms) + if (timeout_ms == 0) return jtag_execute_queue(); else return isc_wait_erase_program(bank, timeout_ms); @@ -409,7 +409,7 @@ static bool need_bit_reverse(const uint8_t *buffer) reference[18] = 0xAA; reference[19] = 0x66; - if (0 == memcmp(reference, buffer, L)) + if (memcmp(reference, buffer, L) == 0) return false; else return true; @@ -444,7 +444,7 @@ static int read_write_data(struct flash_bank *bank, const uint8_t *w_buffer, goto EXIT; } - if ((write_flag) && (0 == offset) && (count >= XCF_PAGE_SIZE)) + if ((write_flag) && (offset == 0) && (count >= XCF_PAGE_SIZE)) revbit = need_bit_reverse(w_buffer); while (count > 0) { @@ -585,7 +585,7 @@ static int xcf_info(struct flash_bank *bank, char *buf, int buf_size) { const struct xcf_priv *priv = bank->driver_priv; - if (false == priv->probed) { + if (!priv->probed) { snprintf(buf, buf_size, "\nXCF flash bank not probed yet\n"); return ERROR_OK; } @@ -598,7 +598,7 @@ static int xcf_probe(struct flash_bank *bank) struct xcf_priv *priv = bank->driver_priv; uint32_t id; - if (true == priv->probed) + if (priv->probed) free(bank->sectors); priv->probed = false; @@ -629,7 +629,7 @@ static int xcf_probe(struct flash_bank *bank) } bank->sectors = malloc(bank->num_sectors * sizeof(struct flash_sector)); - if (NULL == bank->sectors) { + if (bank->sectors == NULL) { LOG_ERROR("No memory for sector table"); return ERROR_FAIL; } @@ -652,7 +652,7 @@ static int xcf_auto_probe(struct flash_bank *bank) { struct xcf_priv *priv = bank->driver_priv; - if (true == priv->probed) + if (priv->probed) return ERROR_OK; else return xcf_probe(bank); diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl index 7d9dbc7..0a26da0 100644 --- a/src/flash/startup.tcl +++ b/src/flash/startup.tcl @@ -6,6 +6,7 @@ # optional args: verify, reset, exit and address # +lappend _telnet_autocomplete_skip program_error proc program_error {description exit} { if {$exit == 1} { echo $description diff --git a/src/helper/command.c b/src/helper/command.c index 4cda7c2..b85fe1e 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -62,12 +62,12 @@ static inline bool jimcmd_is_proc(Jim_Cmd *cmd) return cmd->isproc; } -static inline bool jimcmd_is_ocd_command(Jim_Cmd *cmd) +bool jimcmd_is_oocd_command(Jim_Cmd *cmd) { return !cmd->isproc && cmd->u.native.cmdProc == jim_command_dispatch; } -static inline void *jimcmd_privdata(Jim_Cmd *cmd) +void *jimcmd_privdata(Jim_Cmd *cmd) { return cmd->isproc ? NULL : cmd->u.native.privData; } @@ -144,12 +144,13 @@ static void command_log_capture_finish(struct log_capture_state *state) * Use the internal jimtcl API Jim_CreateCommandObj, not exported by jim.h, * and override the bugged API through preprocessor's macro. * This workaround works only when jimtcl is compiled as OpenOCD submodule. + * It's broken on macOS, so it's currently restricted on Linux only. * If jimtcl is linked-in from a precompiled library, either static or dynamic, * the symbol Jim_CreateCommandObj is not exported and the build will use the * bugged API. * To be removed when OpenOCD will switch to jimtcl 0.81 */ -#if JIM_VERSION == 80 +#if JIM_VERSION == 80 && defined __linux__ static int workaround_createcommand(Jim_Interp *interp, const char *cmdName, Jim_CmdProc *cmdProc, void *privData, Jim_DelCmdProc *delProc); int Jim_CreateCommandObj(Jim_Interp *interp, Jim_Obj *cmdNameObj, @@ -168,7 +169,7 @@ static int workaround_createcommand(Jim_Interp *interp, const char *cmdName, return retval; } #define Jim_CreateCommand workaround_createcommand -#endif /* JIM_VERSION == 80 */ +#endif /* JIM_VERSION == 80 && defined __linux__*/ /* FIXME: end of workaround for memory leak in jimtcl 0.80 */ static int command_retval_set(Jim_Interp *interp, int retval) @@ -260,7 +261,7 @@ static struct command *command_find_from_name(Jim_Interp *interp, const char *na Jim_IncrRefCount(jim_name); Jim_Cmd *cmd = Jim_GetCommand(interp, jim_name, JIM_NONE); Jim_DecrRefCount(interp, jim_name); - if (!cmd || jimcmd_is_proc(cmd) || !jimcmd_is_ocd_command(cmd)) + if (!cmd || jimcmd_is_proc(cmd) || !jimcmd_is_oocd_command(cmd)) return NULL; return jimcmd_privdata(cmd); @@ -342,7 +343,8 @@ static struct command *register_command(struct command_context *context, return NULL; } - LOG_DEBUG("registering '%s'...", full_name); + if (false) /* too noisy with debug_level 3 */ + LOG_DEBUG("registering '%s'...", full_name); int retval = Jim_CreateCommand(context->interp, full_name, jim_command_dispatch, c, command_free); if (retval != JIM_OK) { @@ -440,7 +442,8 @@ int unregister_commands_match(struct command_context *cmd_ctx, const char *forma Jim_DecrRefCount(interp, elem); continue; } - LOG_DEBUG("delete command \"%s\"", name); + if (false) /* too noisy with debug_level 3 */ + LOG_DEBUG("delete command \"%s\"", name); #if JIM_VERSION >= 80 Jim_DeleteCommand(interp, elem); #else @@ -817,14 +820,13 @@ static COMMAND_HELPER(command_help_show, struct help_entry *c, ((c->help != NULL) && (strstr(c->help, cmd_match) != NULL)); if (is_match) { - command_help_show_indent(n); - LOG_USER_N("%s", c->cmd_name); - if (c->usage && strlen(c->usage) > 0) { - LOG_USER_N(" "); - command_help_show_wrap(c->usage, 0, n + 5); - } else - LOG_USER_N("\n"); + char *msg = alloc_printf("%s %s", c->cmd_name, c->usage); + command_help_show_wrap(msg, n, n + 5); + free(msg); + } else { + command_help_show_wrap(c->cmd_name, n, n + 5); + } } if (is_match && show_help) { @@ -864,9 +866,9 @@ static COMMAND_HELPER(command_help_show, struct help_entry *c, stage_msg = " (?mode error?)"; break; } - msg = alloc_printf("%s%s", c->help ? : "", stage_msg); + msg = alloc_printf("%s%s", c->help ? c->help : "", stage_msg); } else - msg = alloc_printf("%s", c->help ? : ""); + msg = alloc_printf("%s", c->help ? c->help : ""); if (NULL != msg) { command_help_show_wrap(msg, n + 3, n + 3); @@ -1018,7 +1020,7 @@ static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv) Jim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE); Jim_DecrRefCount(interp, s); free(full_name); - if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_ocd_command(cmd))) { + if (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_oocd_command(cmd))) { Jim_SetResultString(interp, "unknown", -1); return JIM_OK; } diff --git a/src/helper/command.h b/src/helper/command.h index 68f4c14..719c94b 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -85,6 +85,17 @@ struct command_invocation { }; /** + * Return true if the command @c cmd is registered by OpenOCD. + */ +bool jimcmd_is_oocd_command(Jim_Cmd *cmd); + +/** + * Return the pointer to the command's private data specified during the + * registration of command @a cmd . + */ +void *jimcmd_privdata(Jim_Cmd *cmd); + +/** * Command handlers may be defined with more parameters than the base * set provided by command.c. This macro uses C99 magic to allow * defining all such derivative types using this macro. @@ -427,6 +438,48 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t); COMMAND_PARSE_NUMBER(target_addr, in, out) /** + * @brief parses the command argument at position @a argn into @a out + * as a @a type, or prints a command error referring to @a name_str + * and passes the error code to the caller. @a argn will be incremented + * if no error occurred. Otherwise the calling function will return + * the error code produced by the parsing function. + * + * This function may cause the calling function to return immediately, + * so it should be used carefully to avoid leaking resources. In most + * situations, parsing should be completed in full before proceeding + * to allocate resources, and this strategy will most prevents leaks. + */ +#define COMMAND_PARSE_ADDITIONAL_NUMBER(type, argn, out, name_str) \ + do { \ + if (argn+1 >= CMD_ARGC || CMD_ARGV[argn+1][0] == '-') { \ + command_print(CMD, "no " name_str " given"); \ + return ERROR_FAIL; \ + } \ + ++argn; \ + COMMAND_PARSE_NUMBER(type, CMD_ARGV[argn], out); \ + } while (0) + +/** + * @brief parses the command argument at position @a argn into @a out + * as a @a type if the argument @a argn does not start with '-'. + * and passes the error code to the caller. @a argn will be incremented + * if no error occurred. Otherwise the calling function will return + * the error code produced by the parsing function. + * + * This function may cause the calling function to return immediately, + * so it should be used carefully to avoid leaking resources. In most + * situations, parsing should be completed in full before proceeding + * to allocate resources, and this strategy will most prevents leaks. + */ +#define COMMAND_PARSE_OPTIONAL_NUMBER(type, argn, out) \ + do { \ + if (argn+1 < CMD_ARGC && CMD_ARGV[argn+1][0] != '-') { \ + ++argn; \ + COMMAND_PARSE_NUMBER(type, CMD_ARGV[argn], out); \ + } \ + } while (0) + +/** * Parse the string @c as a binary parameter, storing the boolean value * in @c out. The strings @c on and @c off are used to match different * strings for true and false options (e.g. "on" and "off" or diff --git a/src/helper/jim-nvp.c b/src/helper/jim-nvp.c index 2caf18b..746af8e 100644 --- a/src/helper/jim-nvp.c +++ b/src/helper/jim-nvp.c @@ -44,59 +44,59 @@ #include <string.h> #include <jim-nvp.h> -int Jim_GetNvp(Jim_Interp *interp, - Jim_Obj *objPtr, const Jim_Nvp *nvp_table, const Jim_Nvp **result) +int jim_get_nvp(Jim_Interp *interp, + Jim_Obj *objptr, const struct jim_nvp *nvp_table, const struct jim_nvp **result) { - Jim_Nvp *n; + struct jim_nvp *n; int e; - e = Jim_Nvp_name2value_obj(interp, nvp_table, objPtr, &n); + e = jim_nvp_name2value_obj(interp, nvp_table, objptr, &n); if (e == JIM_ERR) return e; /* Success? found? */ if (n->name) { /* remove const */ - *result = (Jim_Nvp *) n; + *result = (struct jim_nvp *)n; return JIM_OK; } else return JIM_ERR; } -Jim_Nvp *Jim_Nvp_name2value_simple(const Jim_Nvp *p, const char *name) +struct jim_nvp *jim_nvp_name2value_simple(const struct jim_nvp *p, const char *name) { while (p->name) { if (0 == strcmp(name, p->name)) break; p++; } - return (Jim_Nvp *) (p); + return (struct jim_nvp *)p; } -Jim_Nvp *Jim_Nvp_name2value_nocase_simple(const Jim_Nvp *p, const char *name) +struct jim_nvp *jim_nvp_name2value_nocase_simple(const struct jim_nvp *p, const char *name) { while (p->name) { if (0 == strcasecmp(name, p->name)) break; p++; } - return (Jim_Nvp *) (p); + return (struct jim_nvp *)p; } -int Jim_Nvp_name2value_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result) +int jim_nvp_name2value_obj(Jim_Interp *interp, const struct jim_nvp *p, Jim_Obj *o, struct jim_nvp **result) { - return Jim_Nvp_name2value(interp, p, Jim_String(o), result); + return jim_nvp_name2value(interp, p, Jim_String(o), result); } -int Jim_Nvp_name2value(Jim_Interp *interp, const Jim_Nvp *_p, const char *name, Jim_Nvp **result) +int jim_nvp_name2value(Jim_Interp *interp, const struct jim_nvp *_p, const char *name, struct jim_nvp **result) { - const Jim_Nvp *p; + const struct jim_nvp *p; - p = Jim_Nvp_name2value_simple(_p, name); + p = jim_nvp_name2value_simple(_p, name); /* result */ if (result) - *result = (Jim_Nvp *) (p); + *result = (struct jim_nvp *)p; /* found? */ if (p->name) @@ -105,23 +105,23 @@ int Jim_Nvp_name2value(Jim_Interp *interp, const Jim_Nvp *_p, const char *name, return JIM_ERR; } -int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp, - const Jim_Nvp *p, +int jim_nvp_name2value_obj_nocase(Jim_Interp *interp, + const struct jim_nvp *p, Jim_Obj *o, - Jim_Nvp **puthere) + struct jim_nvp **puthere) { - return Jim_Nvp_name2value_nocase(interp, p, Jim_String(o), puthere); + return jim_nvp_name2value_nocase(interp, p, Jim_String(o), puthere); } -int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const Jim_Nvp *_p, const char *name, - Jim_Nvp **puthere) +int jim_nvp_name2value_nocase(Jim_Interp *interp, const struct jim_nvp *_p, const char *name, + struct jim_nvp **puthere) { - const Jim_Nvp *p; + const struct jim_nvp *p; - p = Jim_Nvp_name2value_nocase_simple(_p, name); + p = jim_nvp_name2value_nocase_simple(_p, name); if (puthere) - *puthere = (Jim_Nvp *) (p); + *puthere = (struct jim_nvp *)p; /* found */ if (p->name) return JIM_OK; @@ -129,7 +129,7 @@ int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const Jim_Nvp *_p, const char return JIM_ERR; } -int Jim_Nvp_value2name_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim_Nvp **result) +int jim_nvp_value2name_obj(Jim_Interp *interp, const struct jim_nvp *p, Jim_Obj *o, struct jim_nvp **result) { int e; jim_wide w; @@ -138,27 +138,27 @@ int Jim_Nvp_value2name_obj(Jim_Interp *interp, const Jim_Nvp *p, Jim_Obj *o, Jim if (e != JIM_OK) return e; - return Jim_Nvp_value2name(interp, p, w, result); + return jim_nvp_value2name(interp, p, w, result); } -Jim_Nvp *Jim_Nvp_value2name_simple(const Jim_Nvp *p, int value) +struct jim_nvp *jim_nvp_value2name_simple(const struct jim_nvp *p, int value) { while (p->name) { if (value == p->value) break; p++; } - return (Jim_Nvp *) (p); + return (struct jim_nvp *)p; } -int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *_p, int value, Jim_Nvp **result) +int jim_nvp_value2name(Jim_Interp *interp, const struct jim_nvp *_p, int value, struct jim_nvp **result) { - const Jim_Nvp *p; + const struct jim_nvp *p; - p = Jim_Nvp_value2name_simple(_p, value); + p = jim_nvp_value2name_simple(_p, value); if (result) - *result = (Jim_Nvp *) (p); + *result = (struct jim_nvp *)p; if (p->name) return JIM_OK; @@ -166,7 +166,7 @@ int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *_p, int value, Jim_Nvp return JIM_ERR; } -int Jim_GetOpt_Setup(Jim_GetOptInfo *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv) +int jim_getopt_setup(struct jim_getopt_info *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv) { memset(p, 0, sizeof(*p)); p->interp = interp; @@ -176,7 +176,7 @@ int Jim_GetOpt_Setup(Jim_GetOptInfo *p, Jim_Interp *interp, int argc, Jim_Obj *c return JIM_OK; } -void Jim_GetOpt_Debug(Jim_GetOptInfo *p) +void jim_getopt_debug(struct jim_getopt_info *p) { int x; @@ -186,7 +186,7 @@ void Jim_GetOpt_Debug(Jim_GetOptInfo *p) fprintf(stderr, "-------\n"); } -int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere) +int jim_getopt_obj(struct jim_getopt_info *goi, Jim_Obj **puthere) { Jim_Obj *o; @@ -205,13 +205,13 @@ int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere) return JIM_ERR; } -int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len) +int jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len) { int r; Jim_Obj *o; const char *cp; - r = Jim_GetOpt_Obj(goi, &o); + r = jim_getopt_obj(goi, &o); if (r == JIM_OK) { cp = Jim_GetString(o, len); if (puthere) { @@ -221,7 +221,7 @@ int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len) return r; } -int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere) +int jim_getopt_double(struct jim_getopt_info *goi, double *puthere) { int r; Jim_Obj *o; @@ -230,7 +230,7 @@ int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere) if (puthere == NULL) puthere = &_safe; - r = Jim_GetOpt_Obj(goi, &o); + r = jim_getopt_obj(goi, &o); if (r == JIM_OK) { r = Jim_GetDouble(goi->interp, o, puthere); if (r != JIM_OK) @@ -239,7 +239,7 @@ int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere) return r; } -int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere) +int jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere) { int r; Jim_Obj *o; @@ -248,37 +248,37 @@ int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere) if (puthere == NULL) puthere = &_safe; - r = Jim_GetOpt_Obj(goi, &o); + r = jim_getopt_obj(goi, &o); if (r == JIM_OK) r = Jim_GetWide(goi->interp, o, puthere); return r; } -int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *nvp, Jim_Nvp **puthere) +int jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *nvp, struct jim_nvp **puthere) { - Jim_Nvp *_safe; + struct jim_nvp *_safe; Jim_Obj *o; int e; if (puthere == NULL) puthere = &_safe; - e = Jim_GetOpt_Obj(goi, &o); + e = jim_getopt_obj(goi, &o); if (e == JIM_OK) - e = Jim_Nvp_name2value_obj(goi->interp, nvp, o, puthere); + e = jim_nvp_name2value_obj(goi->interp, nvp, o, puthere); return e; } -void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *nvptable, int hadprefix) +void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *nvptable, int hadprefix) { if (hadprefix) - Jim_SetResult_NvpUnknown(goi->interp, goi->argv[-2], goi->argv[-1], nvptable); + jim_set_result_nvp_unknown(goi->interp, goi->argv[-2], goi->argv[-1], nvptable); else - Jim_SetResult_NvpUnknown(goi->interp, NULL, goi->argv[-1], nvptable); + jim_set_result_nvp_unknown(goi->interp, NULL, goi->argv[-1], nvptable); } -int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere) +int jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere) { int _safe; Jim_Obj *o; @@ -286,14 +286,14 @@ int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere if (puthere == NULL) puthere = &_safe; - e = Jim_GetOpt_Obj(goi, &o); + e = jim_getopt_obj(goi, &o); if (e == JIM_OK) e = Jim_GetEnum(goi->interp, o, lookup, puthere, "option", JIM_ERRMSG); return e; } -void Jim_SetResult_NvpUnknown(Jim_Interp *interp, - Jim_Obj *param_name, Jim_Obj *param_value, const Jim_Nvp *nvp) +void jim_set_result_nvp_unknown(Jim_Interp *interp, + Jim_Obj *param_name, Jim_Obj *param_value, const struct jim_nvp *nvp) { if (param_name) Jim_SetResultFormatted(interp, @@ -318,7 +318,7 @@ void Jim_SetResult_NvpUnknown(Jim_Interp *interp, } } -const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +const char *jim_debug_argv_string(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { static Jim_Obj *debug_string_obj; diff --git a/src/helper/jim-nvp.h b/src/helper/jim-nvp.h index 4c4dc8f..00e4af9 100644 --- a/src/helper/jim-nvp.h +++ b/src/helper/jim-nvp.h @@ -62,7 +62,7 @@ * * Example: * \code - * const Jim_Nvp yn[] = { + * const struct jim_nvp yn[] = { * { "yes", 1 }, * { "no" , 0 }, * { "yep", 1 }, @@ -70,60 +70,60 @@ * { NULL, -1 }, * }; * - * Jim_Nvp *result - * e = Jim_Nvp_name2value(interp, yn, "y", &result); + * struct jim_nvp *result + * e = jim_nvp_name2value(interp, yn, "y", &result); * returns &yn[0]; - * e = Jim_Nvp_name2value(interp, yn, "n", &result); + * e = jim_nvp_name2value(interp, yn, "n", &result); * returns &yn[1]; - * e = Jim_Nvp_name2value(interp, yn, "Blah", &result); + * e = jim_nvp_name2value(interp, yn, "Blah", &result); * returns &yn[4]; * \endcode * * During the number2name operation, the first matching value is returned. */ -typedef struct { +struct jim_nvp { const char *name; int value; -} Jim_Nvp; +}; -int Jim_GetNvp(Jim_Interp *interp, - Jim_Obj *objPtr, - const Jim_Nvp *nvp_table, - const Jim_Nvp **result); +int jim_get_nvp(Jim_Interp *interp, + Jim_Obj *objptr, + const struct jim_nvp *nvp_table, + const struct jim_nvp **result); /* Name Value Pairs Operations */ -Jim_Nvp *Jim_Nvp_name2value_simple(const Jim_Nvp *nvp_table, const char *name); -Jim_Nvp *Jim_Nvp_name2value_nocase_simple(const Jim_Nvp *nvp_table, const char *name); -Jim_Nvp *Jim_Nvp_value2name_simple(const Jim_Nvp *nvp_table, int v); +struct jim_nvp *jim_nvp_name2value_simple(const struct jim_nvp *nvp_table, const char *name); +struct jim_nvp *jim_nvp_name2value_nocase_simple(const struct jim_nvp *nvp_table, const char *name); +struct jim_nvp *jim_nvp_value2name_simple(const struct jim_nvp *nvp_table, int v); -int Jim_Nvp_name2value(Jim_Interp *interp, - const Jim_Nvp *nvp_table, +int jim_nvp_name2value(Jim_Interp *interp, + const struct jim_nvp *nvp_table, const char *name, - Jim_Nvp **result); -int Jim_Nvp_name2value_nocase(Jim_Interp *interp, - const Jim_Nvp *nvp_table, + struct jim_nvp **result); +int jim_nvp_name2value_nocase(Jim_Interp *interp, + const struct jim_nvp *nvp_table, const char *name, - Jim_Nvp **result); -int Jim_Nvp_value2name(Jim_Interp *interp, const Jim_Nvp *nvp_table, int value, Jim_Nvp **result); + struct jim_nvp **result); +int jim_nvp_value2name(Jim_Interp *interp, const struct jim_nvp *nvp_table, int value, struct jim_nvp **result); -int Jim_Nvp_name2value_obj(Jim_Interp *interp, - const Jim_Nvp *nvp_table, +int jim_nvp_name2value_obj(Jim_Interp *interp, + const struct jim_nvp *nvp_table, Jim_Obj *name_obj, - Jim_Nvp **result); -int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp, - const Jim_Nvp *nvp_table, + struct jim_nvp **result); +int jim_nvp_name2value_obj_nocase(Jim_Interp *interp, + const struct jim_nvp *nvp_table, Jim_Obj *name_obj, - Jim_Nvp **result); -int Jim_Nvp_value2name_obj(Jim_Interp *interp, - const Jim_Nvp *nvp_table, + struct jim_nvp **result); +int jim_nvp_value2name_obj(Jim_Interp *interp, + const struct jim_nvp *nvp_table, Jim_Obj *value_obj, - Jim_Nvp **result); + struct jim_nvp **result); /** prints a nice 'unknown' parameter error message to the 'result' */ -void Jim_SetResult_NvpUnknown(Jim_Interp *interp, +void jim_set_result_nvp_unknown(Jim_Interp *interp, Jim_Obj *param_name, Jim_Obj *param_value, - const Jim_Nvp *nvp_table); + const struct jim_nvp *nvp_table); /** Debug: convert argc/argv into a printable string for printf() debug * @@ -142,7 +142,7 @@ void Jim_SetResult_NvpUnknown(Jim_Interp *interp, * fclose(fp); * \endcode */ -const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv); +const char *jim_debug_argv_string(Jim_Interp *interp, int argc, Jim_Obj *const *argv); /** A TCL -ish GetOpt like code. @@ -157,25 +157,25 @@ const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *a * Only supports tcl type options, like "-foo 123" */ -typedef struct jim_getopt { +struct jim_getopt_info { Jim_Interp *interp; int argc; Jim_Obj *const *argv; int isconfigure; /* non-zero if configure */ -} Jim_GetOptInfo; +}; /** GetOpt - how to. * * Example (short and incomplete): * \code - * Jim_GetOptInfo goi; + * struct jim_getopt_info goi; * - * Jim_GetOpt_Setup(&goi, interp, argc, argv); + * jim_getopt_setup(&goi, interp, argc, argv); * * while (goi.argc) { - * e = Jim_GetOpt_Nvp(&goi, nvp_options, &n); + * e = jim_getopt_nvp(&goi, nvp_options, &n); * if (e != JIM_OK) { - * Jim_GetOpt_NvpUnknown(&goi, nvp_options, 0); + * jim_getopt_nvp_unknown(&goi, nvp_options, 0); * return e; * } * @@ -187,16 +187,16 @@ typedef struct jim_getopt { * if (goi.argc < 1) { * .. not enough args error .. * } - * Jim_GetOpt_String(&goi, &cp, NULL); + * jim_getopt_string(&goi, &cp, NULL); * printf("FIRSTNAME: %s\n", cp); * case AGE: - * Jim_GetOpt_Wide(&goi, &w); + * jim_getopt_wide(&goi, &w); * printf("AGE: %d\n", (int)(w)); * break; * case POLITICS: - * e = Jim_GetOpt_Nvp(&goi, nvp_politics, &n); + * e = jim_getopt_nvp(&goi, nvp_politics, &n); * if (e != JIM_OK) { - * Jim_GetOpt_NvpUnknown(&goi, nvp_politics, 1); + * jim_getopt_nvp_unknown(&goi, nvp_politics, 1); * return e; * } * } @@ -214,13 +214,13 @@ typedef struct jim_getopt { * \param argv - argv (will be copied) * * \code - * Jim_GetOptInfo goi; + * struct jim_getopt_info goi; * * Jim_GetOptSetup(&goi, interp, argc, argv); * \endcode */ -int Jim_GetOpt_Setup(Jim_GetOptInfo *goi, +int jim_getopt_setup(struct jim_getopt_info *goi, Jim_Interp *interp, int argc, Jim_Obj *const *argv); @@ -229,7 +229,7 @@ int Jim_GetOpt_Setup(Jim_GetOptInfo *goi, /** Debug - Dump parameters to stderr * \param goi - current parameters */ -void Jim_GetOpt_Debug(Jim_GetOptInfo *goi); +void jim_getopt_debug(struct jim_getopt_info *goi); /** Remove argv[0] from the list. * @@ -237,7 +237,7 @@ void Jim_GetOpt_Debug(Jim_GetOptInfo *goi); * \param puthere - where param is put * */ -int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere); +int jim_getopt_obj(struct jim_getopt_info *goi, Jim_Obj **puthere); /** Remove argv[0] as string. * @@ -245,7 +245,7 @@ int Jim_GetOpt_Obj(Jim_GetOptInfo *goi, Jim_Obj **puthere); * \param puthere - where param is put * \param len - return its length */ -int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len); +int jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len); /** Remove argv[0] as double. * @@ -253,14 +253,14 @@ int Jim_GetOpt_String(Jim_GetOptInfo *goi, const char **puthere, int *len); * \param puthere - where param is put. * */ -int Jim_GetOpt_Double(Jim_GetOptInfo *goi, double *puthere); +int jim_getopt_double(struct jim_getopt_info *goi, double *puthere); /** Remove argv[0] as wide. * * \param goi - get opt info * \param puthere - where param is put. */ -int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere); +int jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere); /** Remove argv[0] as NVP. * @@ -269,7 +269,7 @@ int Jim_GetOpt_Wide(Jim_GetOptInfo *goi, jim_wide *puthere); * \param puthere - where param is put. * */ -int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, Jim_Nvp **puthere); +int jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *lookup, struct jim_nvp **puthere); /** Create an appropriate error message for an NVP. * @@ -289,20 +289,20 @@ int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, Jim_Nvp **puthere * * while (goi.argc) { * // Get the next option - * e = Jim_GetOpt_Nvp(&goi, cmd_options, &n); + * e = jim_getopt_nvp(&goi, cmd_options, &n); * if (e != JIM_OK) { * // option was not recognized * // pass 'hadprefix = 0' because there is no prefix - * Jim_GetOpt_NvpUnknown(&goi, cmd_options, 0); + * jim_getopt_nvp_unknown(&goi, cmd_options, 0); * return e; * } * * switch (n->value) { * case OPT_SEX: * // handle: --sex male | female | lots | needmore - * e = Jim_GetOpt_Nvp(&goi, &nvp_sex, &n); + * e = jim_getopt_nvp(&goi, &nvp_sex, &n); * if (e != JIM_OK) { - * Jim_GetOpt_NvpUnknown(&ogi, nvp_sex, 1); + * jim_getopt_nvp_unknown(&ogi, nvp_sex, 1); * return e; * } * printf("Code: (%d) is %s\n", n->value, n->name); @@ -314,7 +314,7 @@ int Jim_GetOpt_Nvp(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, Jim_Nvp **puthere * \endcode * */ -void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, int hadprefix); +void jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *lookup, int hadprefix); /** Remove argv[0] as Enum @@ -324,6 +324,146 @@ void Jim_GetOpt_NvpUnknown(Jim_GetOptInfo *goi, const Jim_Nvp *lookup, int hadpr * \param puthere - where param is put. * */ -int Jim_GetOpt_Enum(Jim_GetOptInfo *goi, const char *const *lookup, int *puthere); +int jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere); + +/* + * DEPRECATED API + * Do not use these API anymore, as they do not comply with OpenOCD coding style + * They are listed here to avoid breaking build after merge of patches already queued in gerrit + */ + +static inline __attribute__ ((deprecated)) +const char *Jim_Debug_ArgvString(Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return jim_debug_argv_string(interp, argc, argv); +} + +static inline __attribute__ ((deprecated)) +int Jim_GetNvp(Jim_Interp *interp, Jim_Obj *objptr, const struct jim_nvp *nvp_table, const struct jim_nvp **result) +{ + return jim_get_nvp(interp, objptr, nvp_table, result); +} + +static inline __attribute__ ((deprecated)) +void Jim_GetOpt_Debug(struct jim_getopt_info *goi) +{ + jim_getopt_debug(goi); +} + +static inline __attribute__ ((deprecated)) +int Jim_GetOpt_Double(struct jim_getopt_info *goi, double *puthere) +{ + return jim_getopt_double(goi, puthere); +} + +static inline __attribute__ ((deprecated)) +int Jim_GetOpt_Enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere) +{ + return jim_getopt_enum(goi, lookup, puthere); +} + +static inline __attribute__ ((deprecated)) +int Jim_GetOpt_Nvp(struct jim_getopt_info *goi, const struct jim_nvp *lookup, struct jim_nvp **puthere) +{ + return jim_getopt_nvp(goi, lookup, puthere); +} + +static inline __attribute__ ((deprecated)) +void Jim_GetOpt_NvpUnknown(struct jim_getopt_info *goi, const struct jim_nvp *lookup, int hadprefix) +{ + jim_getopt_nvp_unknown(goi, lookup, hadprefix); +} + +static inline __attribute__ ((deprecated)) +int Jim_GetOpt_Obj(struct jim_getopt_info *goi, Jim_Obj **puthere) +{ + return jim_getopt_obj(goi, puthere); +} + +static inline __attribute__ ((deprecated)) +int Jim_GetOpt_Setup(struct jim_getopt_info *goi, Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + return jim_getopt_setup(goi, interp, argc, argv); +} + +static inline __attribute__ ((deprecated)) +int Jim_GetOpt_String(struct jim_getopt_info *goi, const char **puthere, int *len) +{ + return jim_getopt_string(goi, puthere, len); +} + +static inline __attribute__ ((deprecated)) +int Jim_GetOpt_Wide(struct jim_getopt_info *goi, jim_wide *puthere) +{ + return jim_getopt_wide(goi, puthere); +} + +static inline __attribute__ ((deprecated)) +int Jim_Nvp_name2value(Jim_Interp *interp, const struct jim_nvp *nvp_table, const char *name, struct jim_nvp **result) +{ + return jim_nvp_name2value(interp, nvp_table, name, result); +} + +static inline __attribute__ ((deprecated)) +int Jim_Nvp_name2value_nocase(Jim_Interp *interp, const struct jim_nvp *nvp_table, const char *name, + struct jim_nvp **result) +{ + return jim_nvp_name2value_nocase(interp, nvp_table, name, result); +} + +static inline __attribute__ ((deprecated)) +struct jim_nvp *Jim_Nvp_name2value_nocase_simple(const struct jim_nvp *nvp_table, const char *name) +{ + return jim_nvp_name2value_nocase_simple(nvp_table, name); +} + +static inline __attribute__ ((deprecated)) +int Jim_Nvp_name2value_obj(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *name_obj, + struct jim_nvp **result) +{ + return jim_nvp_name2value_obj(interp, nvp_table, name_obj, result); +} + +static inline __attribute__ ((deprecated)) +int Jim_Nvp_name2value_obj_nocase(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *name_obj, + struct jim_nvp **result) +{ + return jim_nvp_name2value_obj_nocase(interp, nvp_table, name_obj, result); +} + +static inline __attribute__ ((deprecated)) +struct jim_nvp *Jim_Nvp_name2value_simple(const struct jim_nvp *nvp_table, const char *name) +{ + return jim_nvp_name2value_simple(nvp_table, name); +} + +static inline __attribute__ ((deprecated)) +int Jim_Nvp_value2name(Jim_Interp *interp, const struct jim_nvp *nvp_table, int value, struct jim_nvp **result) +{ + return jim_nvp_value2name(interp, nvp_table, value, result); +} + +static inline __attribute__ ((deprecated)) +int Jim_Nvp_value2name_obj(Jim_Interp *interp, const struct jim_nvp *nvp_table, Jim_Obj *value_obj, + struct jim_nvp **result) +{ + return jim_nvp_value2name_obj(interp, nvp_table, value_obj, result); +} + +static inline __attribute__ ((deprecated)) +struct jim_nvp *Jim_Nvp_value2name_simple(const struct jim_nvp *nvp_table, int v) +{ + return jim_nvp_value2name_simple(nvp_table, v); +} + +static inline __attribute__ ((deprecated)) +void Jim_SetResult_NvpUnknown(Jim_Interp *interp, Jim_Obj *param_name, Jim_Obj *param_value, + const struct jim_nvp *nvp_table) +{ + jim_set_result_nvp_unknown(interp, param_name, param_value, nvp_table); +} + +typedef struct jim_getopt_info Jim_GetOptInfo __attribute__ ((deprecated)); +typedef struct jim_nvp Jim_Nvp __attribute__ ((deprecated)); #endif /* OPENOCD_HELPER_JIM_NVP_H */ diff --git a/src/helper/list.h b/src/helper/list.h index 7f60464..a7cd4ad 100644 --- a/src/helper/list.h +++ b/src/helper/list.h @@ -1,26 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * The content of this file is mainly copied/inspired from Linux kernel + * code in include/linux/list.h, include/linux/types.h + * Last aligned with kernel v5.12: + * - skip the functions hlist_unhashed_lockless() and __list_del_clearprev() + * that are relevant only in kernel; + * - Remove non-standard GCC extension "omitted conditional operand" from + * list_prepare_entry; + * - expand READ_ONCE, WRITE_ONCE, smp_load_acquire, smp_store_release; + * - make comments compatible with doxygen. + * + * There is an example of using this file in contrib/list_example.c. + */ + #ifndef OPENOCD_HELPER_LIST_H #define OPENOCD_HELPER_LIST_H /* begin local changes */ #include <helper/types.h> -#define prefetch(x) ((void)x) #define LIST_POISON1 NULL #define LIST_POISON2 NULL 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 */ /* - * Simple doubly linked list implementation. + * Circular doubly linked list implementation. * * Some of the internal functions ("__xxx") are useful when * manipulating whole lists rather than single entries, as @@ -31,36 +48,58 @@ struct hlist_node { #define LIST_HEAD_INIT(name) { &(name), &(name) } -#define LIST_HEAD(name) \ +#define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) +/** + * INIT_LIST_HEAD - Initialize a list_head structure + * @param list list_head structure to be initialized. + * + * Initializes the list_head to point to itself. If it is a list header, + * the result is an empty list. + */ static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; } +#ifdef CONFIG_DEBUG_LIST +extern bool __list_add_valid(struct list_head *new, + struct list_head *prev, + struct list_head *next); +extern bool __list_del_entry_valid(struct list_head *entry); +#else +static inline bool __list_add_valid(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + return true; +} +static inline bool __list_del_entry_valid(struct list_head *entry) +{ + return true; +} +#endif + /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ -#ifndef CONFIG_DEBUG_LIST static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) + struct list_head *prev, + struct list_head *next) { + if (!__list_add_valid(new, prev, next)) + return; + next->prev = new; new->next = next; new->prev = prev; prev->next = new; } -#else -extern void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next); -#endif /** * list_add - add a new entry @@ -102,28 +141,28 @@ static inline void __list_del(struct list_head *prev, struct list_head *next) prev->next = next; } +/* Ignore kernel __list_del_clearprev() */ + +static inline void __list_del_entry(struct list_head *entry) +{ + if (!__list_del_entry_valid(entry)) + return; + + __list_del(entry->prev, entry->next); +} + /** * list_del - deletes entry from list. * @param entry the element to delete from the list. * Note: list_empty() on entry does not return true after this, the entry is * in an undefined state. */ -#ifndef CONFIG_DEBUG_LIST -static inline void __list_del_entry(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); -} - static inline void list_del(struct list_head *entry) { - __list_del(entry->prev, entry->next); + __list_del_entry(entry); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } -#else -extern void __list_del_entry(struct list_head *entry); -extern void list_del(struct list_head *entry); -#endif /** * list_replace - replace old entry by new one @@ -133,7 +172,7 @@ extern void list_del(struct list_head *entry); * If @a old was empty, it will be overwritten. */ static inline void list_replace(struct list_head *old, - struct list_head *new) + struct list_head *new) { new->next = old->next; new->next->prev = new; @@ -141,14 +180,38 @@ static inline void list_replace(struct list_head *old, new->prev->next = new; } +/** + * list_replace_init - replace old entry by new one and initialize the old one + * @param old the element to be replaced + * @param new the new element to insert + * + * If @a old was empty, it will be overwritten. + */ static inline void list_replace_init(struct list_head *old, - struct list_head *new) + struct list_head *new) { list_replace(old, new); INIT_LIST_HEAD(old); } /** + * list_swap - replace entry1 with entry2 and re-add entry1 at entry2's position + * @param entry1 the location to place entry2 + * @param entry2 the location to place entry1 + */ +static inline void list_swap(struct list_head *entry1, + struct list_head *entry2) +{ + struct list_head *pos = entry2->prev; + + list_del(entry2); + list_replace(entry1, entry2); + if (pos == entry1) + pos = entry2; + list_add(entry1, pos); +} + +/** * list_del_init - deletes entry from list and reinitialize it. * @param entry the element to delete from the list. */ @@ -175,19 +238,53 @@ static inline void list_move(struct list_head *list, struct list_head *head) * @param head the head that will follow our entry */ static inline void list_move_tail(struct list_head *list, - struct list_head *head) + struct list_head *head) { __list_del_entry(list); list_add_tail(list, head); } /** + * list_bulk_move_tail - move a subsection of a list to its tail + * @param head the head that will follow our entry + * @param first the first entry to move + * @param last the last entry to move, can be the same as first + * + * Move all entries between @a first and including @a last before @a head. + * All three entries must belong to the same linked list. + */ +static inline void list_bulk_move_tail(struct list_head *head, + struct list_head *first, + struct list_head *last) +{ + first->prev->next = last->next; + last->next->prev = first->prev; + + head->prev->next = first; + first->prev = head->prev; + + last->next = head; + head->prev = last; +} + +/** + * list_is_first -- tests whether @a list is the first entry in list @a 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) +{ + return list->prev == head; +} + +/** * list_is_last - tests whether @a list is the last entry in list @a head * @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) + const struct list_head *head) { return list->next == head; } @@ -202,6 +299,24 @@ static inline int list_empty(const struct list_head *head) } /** + * list_del_init_careful - deletes entry from list and reinitialize it. + * @param entry the element to delete from the list. + * + * This is the same as list_del_init(), except designed to be used + * together with list_empty_careful() in a way to guarantee ordering + * of other memory operations. + * + * Any memory operations done before a list_del_init_careful() are + * guaranteed to be visible after a list_empty_careful() test. + */ +static inline void list_del_init_careful(struct list_head *entry) +{ + __list_del_entry(entry); + entry->prev = entry; + entry->next = entry; +} + +/** * list_empty_careful - tests whether a list is empty and not being modified * @param head the list to test * @@ -235,6 +350,24 @@ static inline void list_rotate_left(struct list_head *head) } /** + * list_rotate_to_front() - Rotate list to specific item. + * @param list The desired new front of the list. + * @param head The head of the list. + * + * Rotates list so that @a list becomes the new front of the list. + */ +static inline void list_rotate_to_front(struct list_head *list, + struct list_head *head) +{ + /* + * Deletes the list head from the list denoted by @a head and + * places it as the tail of @a list, this effectively rotates the + * list so that @a list is at the front. + */ + list_move_tail(head, list); +} + +/** * list_is_singular - tests whether a list has just one entry. * @param head the list to test. */ @@ -244,7 +377,7 @@ static inline int list_is_singular(const struct list_head *head) } static inline void __list_cut_position(struct list_head *list, - struct list_head *head, struct list_head *entry) + struct list_head *head, struct list_head *entry) { struct list_head *new_first = entry->next; list->next = head->next; @@ -270,12 +403,12 @@ static inline void __list_cut_position(struct list_head *list, * */ static inline void list_cut_position(struct list_head *list, - struct list_head *head, struct list_head *entry) + struct list_head *head, struct list_head *entry) { if (list_empty(head)) return; if (list_is_singular(head) && - (head->next != entry && head != entry)) + (head->next != entry && head != entry)) return; if (entry == head) INIT_LIST_HEAD(list); @@ -283,9 +416,39 @@ static inline void list_cut_position(struct list_head *list, __list_cut_position(list, head, entry); } +/** + * list_cut_before - cut a list into two, before given entry + * @param list a new list to add all removed entries + * @param head a list with entries + * @param entry an entry within head, could be the head itself + * + * This helper moves the initial part of @a head, up to but + * excluding @a entry, from @a head to @a list. You should pass + * in @a entry an element you know is on @a head. @a list should + * be an empty list or a list you do not care about losing + * its data. + * If @a entry == @a head, all entries on @a head are moved to + * @a list. + */ +static inline void list_cut_before(struct list_head *list, + struct list_head *head, + struct list_head *entry) +{ + if (head->next == entry) { + INIT_LIST_HEAD(list); + return; + } + list->next = head->next; + list->next->prev = list; + list->prev = entry->prev; + list->prev->next = list; + head->next = entry; + entry->prev = head; +} + static inline void __list_splice(const struct list_head *list, - struct list_head *prev, - struct list_head *next) + struct list_head *prev, + struct list_head *next) { struct list_head *first = list->next; struct list_head *last = list->prev; @@ -303,7 +466,7 @@ static inline void __list_splice(const struct list_head *list, * @param head the place to add it in the first list. */ static inline void list_splice(const struct list_head *list, - struct list_head *head) + struct list_head *head) { if (!list_empty(list)) __list_splice(list, head, head->next); @@ -315,7 +478,7 @@ static inline void list_splice(const struct list_head *list, * @param head the place to add it in the first list. */ static inline void list_splice_tail(struct list_head *list, - struct list_head *head) + struct list_head *head) { if (!list_empty(list)) __list_splice(list, head->prev, head); @@ -329,7 +492,7 @@ static inline void list_splice_tail(struct list_head *list, * The list at @a list is reinitialised */ static inline void list_splice_init(struct list_head *list, - struct list_head *head) + struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head, head->next); @@ -346,7 +509,7 @@ static inline void list_splice_init(struct list_head *list, * The list at @a list is reinitialised */ static inline void list_splice_tail_init(struct list_head *list, - struct list_head *head) + struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head->prev, head); @@ -358,7 +521,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_entry - get the struct for this entry * @param ptr the &struct list_head pointer. * @param type the type of the struct this is embedded in. - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. */ #define list_entry(ptr, type, member) \ container_of(ptr, type, member) @@ -367,7 +530,7 @@ static inline void list_splice_tail_init(struct list_head *list, * list_first_entry - get the first element from a list * @param ptr the list head to take the element from. * @param type the type of the struct this is embedded in. - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. * * Note, that list is expected to be not empty. */ @@ -375,26 +538,63 @@ static inline void list_splice_tail_init(struct list_head *list, list_entry((ptr)->next, type, member) /** + * list_last_entry - get the last element from a list + * @param ptr the list head to take the element from. + * @param type the type of the struct this is embedded in. + * @param member the name of the list_head within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +/** + * list_first_entry_or_null - get the first element from a list + * @param ptr the list head to take the element from. + * @param type the type of the struct this is embedded in. + * @param member the name of the list_head within the struct. + * + * Note that if the list is empty, it returns NULL. + */ +#define list_first_entry_or_null(ptr, type, member) ({ \ + struct list_head *head__ = (ptr); \ + struct list_head *pos__ = head__->next; \ + pos__ != head__ ? list_entry(pos__, type, member) : NULL; \ +}) + +/** + * list_next_entry - get the next element in list + * @param pos the type * to cursor + * @param member the name of the list_head within the struct. + */ +#define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) + +/** + * list_prev_entry - get the prev element in list + * @param pos the type * to cursor + * @param member the name of the list_head within the struct. + */ +#define list_prev_entry(pos, member) \ + list_entry((pos)->member.prev, typeof(*(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; prefetch(pos->next), pos != (head); \ - pos = pos->next) + for (pos = (head)->next; pos != (head); pos = pos->next) /** - * __list_for_each - iterate over a list + * list_for_each_continue - continue iteration over a list * @param pos the &struct list_head to use as a loop cursor. * @param head the head for your list. * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. + * Continue to iterate over a list, continuing after the current position. */ -#define __list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) +#define list_for_each_continue(pos, head) \ + for (pos = pos->next; pos != (head); pos = pos->next) /** * list_for_each_prev - iterate over a list backwards @@ -402,8 +602,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @param head the head for your list. */ #define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ - pos = pos->prev) + for (pos = (head)->prev; pos != (head); pos = pos->prev) /** * list_for_each_safe - iterate over a list safe against removal of list entry @@ -413,7 +612,7 @@ static inline void list_splice_tail_init(struct list_head *list, */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) + pos = n, n = pos->next) /** * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry @@ -422,148 +621,170 @@ static inline void list_splice_tail_init(struct list_head *list, * @param head the head for your list. */ #define list_for_each_prev_safe(pos, n, head) \ - for (pos = (head)->prev, n = pos->prev; \ - prefetch(pos->prev), pos != (head); \ + for (pos = (head)->prev, n = pos->prev; \ + pos != (head); \ pos = n, n = pos->prev) /** + * list_entry_is_head - test if the entry points to the head of the list + * @param pos the type * to cursor + * @param head the head for your list. + * @param member the name of the list_head within the struct. + */ +#define list_entry_is_head(pos, head, member) \ + (&pos->member == (head)) + +/** * list_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 list_struct within the struct. + * @param member the name of the list_head within the struct. */ #define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) + for (pos = list_first_entry(head, typeof(*pos), member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_next_entry(pos, member)) /** * list_for_each_entry_reverse - iterate backwards 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 list_struct within the struct. + * @param member the name of the list_head within the struct. */ #define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) + for (pos = list_last_entry(head, typeof(*pos), member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_prev_entry(pos, member)) /** * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() * @param pos the type * to use as a start point * @param head the head of the list - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. * * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). */ #define list_prepare_entry(pos, head, member) \ - ((pos) ? : list_entry(head, typeof(*pos), member)) + ((pos) ? (pos) : list_entry(head, typeof(*pos), member)) /** * list_for_each_entry_continue - continue iteration 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 list_struct within the struct. + * @param member the name of the list_head within the struct. * * Continue to iterate over list of given type, continuing after * the current position. */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) +#define list_for_each_entry_continue(pos, head, member) \ + for (pos = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_next_entry(pos, member)) /** * list_for_each_entry_continue_reverse - iterate backwards from the given point * @param pos the type * to use as a loop cursor. * @param head the head for your list. - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. * * Start to iterate over list of given type backwards, continuing after * the current position. */ #define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) + for (pos = list_prev_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_prev_entry(pos, member)) /** * list_for_each_entry_from - iterate over list of given type from the current point * @param pos the type * to use as a loop cursor. * @param head the head for your list. - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. * * Iterate over list of given type, continuing from current position. */ #define list_for_each_entry_from(pos, head, member) \ - for (; prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) + for (; !list_entry_is_head(pos, head, member); \ + pos = list_next_entry(pos, member)) + +/** + * list_for_each_entry_from_reverse - iterate backwards over list of given type + * from the current point + * @param pos the type * to use as a loop cursor. + * @param head the head for your list. + * @param member the name of the list_head within the struct. + * + * Iterate backwards over list of given type, continuing from current position. + */ +#define list_for_each_entry_from_reverse(pos, head, member) \ + for (; !list_entry_is_head(pos, head, member); \ + pos = list_prev_entry(pos, member)) /** * list_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 another type * to use as temporary storage * @param head the head for your list. - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) + for (pos = list_first_entry(head, typeof(*pos), member), \ + n = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = n, n = list_next_entry(n, member)) /** * list_for_each_entry_safe_continue - continue list iteration safe against removal * @param pos the type * to use as a loop cursor. * @param n another type * to use as temporary storage * @param head the head for your list. - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. * * Iterate over list of given type, continuing after current point, * safe against removal of list entry. */ -#define list_for_each_entry_safe_continue(pos, n, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) +#define list_for_each_entry_safe_continue(pos, n, head, member) \ + for (pos = list_next_entry(pos, member), \ + n = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = n, n = list_next_entry(n, member)) /** * list_for_each_entry_safe_from - iterate over list from current point safe against removal * @param pos the type * to use as a loop cursor. * @param n another type * to use as temporary storage * @param head the head for your list. - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. * * Iterate over list of given type from current point, safe against * removal of list entry. */ #define list_for_each_entry_safe_from(pos, n, head, member) \ - for (n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) + for (n = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = n, n = list_next_entry(n, member)) /** * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal * @param pos the type * to use as a loop cursor. * @param n another type * to use as temporary storage * @param head the head for your list. - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. * * Iterate backwards over list of given type, safe against removal * of list entry. */ #define list_for_each_entry_safe_reverse(pos, n, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member), \ - n = list_entry(pos->member.prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.prev, typeof(*n), member)) + for (pos = list_last_entry(head, typeof(*pos), member), \ + n = list_prev_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = n, n = list_prev_entry(n, member)) /** * list_safe_reset_next - reset a stale list_for_each_entry_safe loop * @param pos the loop cursor used in the list_for_each_entry_safe loop * @param n temporary storage used in list_for_each_entry_safe - * @param member the name of the list_struct within the struct. + * @param member the name of the list_head within the struct. * * list_safe_reset_next is not safe to use in general if the list may be * modified concurrently (eg. the lock is dropped in the loop body). An @@ -572,7 +793,7 @@ static inline void list_splice_tail_init(struct list_head *list, * completing the current iteration of the loop body. */ #define list_safe_reset_next(pos, n, member) \ - n = list_entry(pos->member.next, typeof(*pos), member) + n = list_next_entry(pos, member) /* * Double linked lists with a single pointer list head. @@ -590,11 +811,25 @@ static inline void INIT_HLIST_NODE(struct hlist_node *h) 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; @@ -604,11 +839,19 @@ 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); @@ -616,6 +859,12 @@ static inline void hlist_del(struct hlist_node *n) 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)) { @@ -624,6 +873,14 @@ static inline void hlist_del_init(struct 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; @@ -634,9 +891,13 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) n->pprev = &h->first; } -/* next must be != NULL */ +/** + * 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) + struct hlist_node *next) { n->pprev = next->pprev; n->next = next; @@ -644,29 +905,68 @@ static inline void hlist_add_before(struct hlist_node *n, *(n->pprev) = n; } -static inline void hlist_add_after(struct hlist_node *n, - struct hlist_node *next) +/** + * 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) { - next->next = n->next; - n->next = next; - next->pprev = &n->next; + n->next = prev->next; + prev->next = n; + n->pprev = &prev->next; - if (next->next) - next->next->pprev = &next->next; + if (n->next) + n->next->pprev = &n->next; } -/* after that we'll appear to be on some hlist and hlist_del will work */ +/** + * 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) + struct hlist_head *new) { new->first = old->first; if (new->first) @@ -677,61 +977,57 @@ static inline void hlist_move_list(struct hlist_head *old, #define hlist_entry(ptr, type, member) container_of(ptr, type, member) #define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ - pos = pos->next) + 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 tpos the type * to use as a loop cursor. - * @param pos the &struct hlist_node to use as a loop cursor. + * @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(tpos, pos, head, member) \ - for (pos = (head)->first; \ - pos && ({ prefetch(pos->next); 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = pos->next) +#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 tpos the type * to use as a loop cursor. - * @param pos the &struct hlist_node to use as a loop cursor. + * @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(tpos, pos, member) \ - for (pos = (pos)->next; \ - pos && ({ prefetch(pos->next); 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = pos->next) +#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 tpos the type * to use as a loop cursor. - * @param pos the &struct hlist_node to use as a loop cursor. + * @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(tpos, pos, member) \ - for (; pos && ({ prefetch(pos->next); 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = pos->next) +#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 tpos the type * to use as a loop cursor. - * @param pos the &struct hlist_node to use as a loop cursor. - * @param n another &struct hlist_node to use as temporary storage + * @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. */ -#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ - for (pos = (head)->first; \ - pos && ({ n = pos->next; 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \ - pos = n) +#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 */ diff --git a/src/helper/log.c b/src/helper/log.c index f5a8062..36b59fe 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -518,3 +518,16 @@ void log_socket_error(const char *socket_desc) LOG_ERROR("Error on socket '%s': errno==%d, message: %s.", socket_desc, error_code, strerror(error_code)); #endif } + +/** + * Find the first non-printable character in the char buffer, return a pointer to it. + * If no such character exists, return NULL. + */ +char *find_nonprint_char(char *buf, unsigned buf_len) +{ + for (unsigned int i = 0; i < buf_len; i++) { + if (!isprint(buf[i])) + return buf + i; + } + return NULL; +} diff --git a/src/helper/log.h b/src/helper/log.h index f2ba0da..34ff835 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -100,6 +100,8 @@ char *alloc_vprintf(const char *fmt, va_list ap); char *alloc_printf(const char *fmt, ...) __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 2))); +char *find_nonprint_char(char *buf, unsigned buf_len); + extern int debug_level; /* Avoid fn call and building parameter list if we're not outputting the information. diff --git a/src/helper/time_support.h b/src/helper/time_support.h index 3c7d425..b83c0ac 100644 --- a/src/helper/time_support.h +++ b/src/helper/time_support.h @@ -46,7 +46,7 @@ struct duration { /** Update the duration->start field to start the @a duration measurement. */ int duration_start(struct duration *duration); -/** Update the duration->elapsed field to finish the @a duration measurment. */ +/** Update the duration->elapsed field to finish the @a duration measurement. */ int duration_measure(struct duration *duration); /** @returns Elapsed time in seconds. */ diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 97ede50..b1b5fe5 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -47,8 +47,8 @@ const char * const jtag_only[] = { "jtag", NULL }; static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); + 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... */ @@ -58,7 +58,7 @@ static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) return JIM_ERR; } const char *name = adapter_driver ? adapter_driver->name : NULL; - Jim_SetResultString(goi.interp, name ? : "undefined", -1); + Jim_SetResultString(goi.interp, name ? name : "undefined", -1); return JIM_OK; } @@ -580,7 +580,7 @@ static const struct command_registration adapter_command_handlers[] = { .handler = adapter_transports_command, .mode = COMMAND_CONFIG, .help = "Declare transports the adapter supports.", - .usage = "transport ... ", + .usage = "transport ...", }, { .name = "usb", diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c index 160eb11..86e9d16 100644 --- a/src/jtag/aice/aice_interface.c +++ b/src/jtag/aice/aice_interface.c @@ -436,7 +436,7 @@ static const struct command_registration aice_subcommand_handlers[] = { .handler = &aice_handle_aice_desc_command, .mode = COMMAND_CONFIG, .help = "set the aice device description", - .usage = "[desciption string]", + .usage = "[description string]", }, { .name = "serial", diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c index c02a42f..322d8ae 100644 --- a/src/jtag/aice/aice_transport.c +++ b/src/jtag/aice/aice_transport.c @@ -30,11 +30,11 @@ #include <string.h> /* */ -static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, +static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi, struct jtag_tap *pTap) { jim_wide w; - int e = Jim_GetOpt_Wide(goi, &w); + int e = jim_getopt_wide(goi, &w); if (e != JIM_OK) { Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name); @@ -63,14 +63,14 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, #define NTAP_OPT_EXPECTED_ID 0 /* */ -static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi) +static int jim_aice_newtap_cmd(struct jim_getopt_info *goi) { struct jtag_tap *pTap; int x; int e; - Jim_Nvp *n; + struct jim_nvp *n; char *cp; - const Jim_Nvp opts[] = { + const struct jim_nvp opts[] = { {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID}, {.name = NULL, .value = -1}, }; @@ -92,10 +92,10 @@ static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi) } const char *tmp; - Jim_GetOpt_String(goi, &tmp, NULL); + jim_getopt_string(goi, &tmp, NULL); pTap->chip = strdup(tmp); - Jim_GetOpt_String(goi, &tmp, NULL); + jim_getopt_string(goi, &tmp, NULL); pTap->tapname = strdup(tmp); /* name + dot + name + null */ @@ -108,9 +108,9 @@ static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi) pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc); while (goi->argc) { - e = Jim_GetOpt_Nvp(goi, opts, &n); + e = jim_getopt_nvp(goi, opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, opts, 0); + jim_getopt_nvp_unknown(goi, opts, 0); free(cp); free(pTap); return e; @@ -138,8 +138,8 @@ static int jim_aice_newtap_cmd(Jim_GetOptInfo *goi) /* */ static int jim_aice_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); return jim_aice_newtap_cmd(&goi); } @@ -246,8 +246,8 @@ static int aice_init_reset(struct command_context *cmd_ctx) static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { int e = ERROR_OK; - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + 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; @@ -265,8 +265,8 @@ static int jim_aice_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj * const static int jim_aice_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + 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; diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index b59c8f9..b970331 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -2628,7 +2628,7 @@ static int aice_usb_halt(uint32_t coreid) if (core_info[coreid].debug_under_dex_on) { if (core_info[coreid].dex_use_psw_on == false) { - /* under debug 'debug mode', force $psw to 'debug mode' bahavior */ + /* under debug 'debug mode', force $psw to 'debug mode' behavior */ /* !!!NOTICE!!! this is workaround for debug 'debug mode'. * it is only for debugging 'debug exception handler' purpose. * after openocd detaches from target, target behavior is diff --git a/src/jtag/core.c b/src/jtag/core.c index 37924aa..456faf7 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -45,6 +45,9 @@ #include "svf/svf.h" #include "xsvf/xsvf.h" +/* ipdbg are utilities to debug IP-cores. It uses JTAG for transport. */ +#include "server/ipdbg.h" + /** The number of JTAG queue flushes (for profiling and debugging purposes). */ static int jtag_flush_queue_count; @@ -487,7 +490,7 @@ void jtag_add_tlr(void) /** * If supported by the underlying adapter, this clocks a raw bit sequence - * onto TMS for switching betwen JTAG and SWD modes. + * onto TMS for switching between JTAG and SWD modes. * * DO NOT use this to bypass the integrity checks and logging provided * by the jtag_add_pathmove() and jtag_add_statemove() calls. @@ -1340,7 +1343,7 @@ static int jtag_validate_ircapture(void) int chain_pos = 0; int retval; - /* when autoprobing, accomodate huge IR lengths */ + /* when autoprobing, accommodate huge IR lengths */ for (tap = NULL, total_ir_length = 0; (tap = jtag_tap_next_enabled(tap)) != NULL; total_ir_length += tap->ir_length) { @@ -1452,7 +1455,7 @@ void jtag_tap_init(struct jtag_tap *tap) unsigned ir_len_bytes; /* if we're autoprobing, cope with potentially huge ir_length */ - ir_len_bits = tap->ir_length ? : JTAG_IRLEN_MAX; + ir_len_bits = tap->ir_length ? tap->ir_length : JTAG_IRLEN_MAX; ir_len_bytes = DIV_ROUND_UP(ir_len_bits, 8); tap->expected = calloc(1, ir_len_bytes); @@ -1975,7 +1978,12 @@ static int jtag_select(struct command_context *ctx) if (retval != ERROR_OK) return retval; - return xsvf_register_commands(ctx); + retval = xsvf_register_commands(ctx); + + if (retval != ERROR_OK) + return retval; + + return ipdbg_register_commands(ctx); } static struct transport jtag_transport = { diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c index 26e576b..4062ace 100644 --- a/src/jtag/drivers/cmsis_dap.c +++ b/src/jtag/drivers/cmsis_dap.c @@ -1,4 +1,7 @@ /*************************************************************************** + * Copyright (C) 2021 by Adrian Negreanu * + * groleo@gmail.com * + * * * Copyright (C) 2018 by Mickaël Thomas * * mickael9@gmail.com * * * @@ -41,6 +44,7 @@ #include <jtag/interface.h> #include <jtag/commands.h> #include <jtag/tcl.h> +#include <target/cortex_m.h> #include "cmsis_dap.h" @@ -96,9 +100,12 @@ static bool swd_mode; #define INFO_ID_CAPS 0xf0 /* byte */ #define INFO_ID_PKT_CNT 0xfe /* byte */ #define INFO_ID_PKT_SZ 0xff /* short */ +#define INFO_ID_SWO_BUF_SZ 0xfd /* word */ -#define INFO_CAPS_SWD 0x01 -#define INFO_CAPS_JTAG 0x02 +#define INFO_CAPS_SWD BIT(0) +#define INFO_CAPS_JTAG BIT(1) +#define INFO_CAPS_SWO_UART BIT(2) +#define INFO_CAPS_SWO_MANCHESTER BIT(3) /* CMD_LED */ #define LED_ID_CONNECT 0x00 @@ -163,12 +170,44 @@ static bool swd_mode; #define DAP_OK 0 #define DAP_ERROR 0xFF +/* CMSIS-DAP SWO Commands */ +#define CMD_DAP_SWO_TRANSPORT 0x17 +#define CMD_DAP_SWO_MODE 0x18 +#define CMD_DAP_SWO_BAUDRATE 0x19 +#define CMD_DAP_SWO_CONTROL 0x1A +#define CMD_DAP_SWO_STATUS 0x1B +#define CMD_DAP_SWO_DATA 0x1C +#define CMD_DAP_SWO_EX_STATUS 0x1E + +/* SWO transport mode for reading trace data */ +#define DAP_SWO_TRANSPORT_NONE 0 +#define DAP_SWO_TRANSPORT_DATA 1 +#define DAP_SWO_TRANSPORT_WINUSB 2 + +/* SWO trace capture mode */ +#define DAP_SWO_MODE_OFF 0 +#define DAP_SWO_MODE_UART 1 +#define DAP_SWO_MODE_MANCHESTER 2 + +/* SWO trace data capture */ +#define DAP_SWO_CONTROL_STOP 0 +#define DAP_SWO_CONTROL_START 1 + +/* SWO trace status */ +#define DAP_SWO_STATUS_CAPTURE_INACTIVE 0 +#define DAP_SWO_STATUS_CAPTURE_ACTIVE 1 +#define DAP_SWO_STATUS_CAPTURE_MASK BIT(0) +#define DAP_SWO_STATUS_STREAM_ERROR_MASK BIT(6) +#define DAP_SWO_STATUS_BUFFER_OVERRUN_MASK BIT(7) + /* CMSIS-DAP Vendor Commands * None as yet... */ static const char * const info_caps_str[] = { "SWD Supported", - "JTAG Supported" + "JTAG Supported", + "SWO-UART Supported", + "SWO-MANCHESTER Supported" }; struct pending_transfer_result { @@ -338,9 +377,8 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen) return ERROR_OK; } -static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input) +static int cmsis_dap_cmd_dap_swj_pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input) { - int retval; uint8_t *command = cmsis_dap_handle->command; command[0] = CMD_DAP_SWJ_PINS; @@ -348,8 +386,7 @@ static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay command[2] = mask; h_u32_to_le(&command[3], delay); - retval = cmsis_dap_xfer(cmsis_dap_handle, 7); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 7); if (retval != ERROR_OK) { LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_PINS failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -361,9 +398,8 @@ static int cmsis_dap_cmd_DAP_SWJ_Pins(uint8_t pins, uint8_t mask, uint32_t delay return ERROR_OK; } -static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock) +static int cmsis_dap_cmd_dap_swj_clock(uint32_t swj_clock) { - int retval; uint8_t *command = cmsis_dap_handle->command; /* set clock in Hz */ @@ -372,8 +408,7 @@ static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock) command[0] = CMD_DAP_SWJ_CLOCK; h_u32_to_le(&command[1], swj_clock); - retval = cmsis_dap_xfer(cmsis_dap_handle, 5); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 5); if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { LOG_ERROR("CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -383,9 +418,8 @@ static int cmsis_dap_cmd_DAP_SWJ_Clock(uint32_t swj_clock) } /* clock a sequence of bits out on TMS, to change JTAG states */ -static int cmsis_dap_cmd_DAP_SWJ_Sequence(uint8_t s_len, const uint8_t *sequence) +static int cmsis_dap_cmd_dap_swj_sequence(uint8_t s_len, const uint8_t *sequence) { - int retval; uint8_t *command = cmsis_dap_handle->command; #ifdef CMSIS_DAP_JTAG_DEBUG @@ -400,23 +434,21 @@ static int cmsis_dap_cmd_DAP_SWJ_Sequence(uint8_t s_len, const uint8_t *sequence command[1] = s_len; bit_copy(&command[2], 0, sequence, 0, s_len); - retval = cmsis_dap_xfer(cmsis_dap_handle, 2 + DIV_ROUND_UP(s_len, 8)); + int retval = cmsis_dap_xfer(cmsis_dap_handle, 2 + DIV_ROUND_UP(s_len, 8)); if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) return ERROR_FAIL; return ERROR_OK; } -static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data) +static int cmsis_dap_cmd_dap_info(uint8_t info, uint8_t **data) { - int retval; uint8_t *command = cmsis_dap_handle->command; command[0] = CMD_DAP_INFO; command[1] = info; - retval = cmsis_dap_xfer(cmsis_dap_handle, 2); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 2); if (retval != ERROR_OK) { LOG_ERROR("CMSIS-DAP command CMD_INFO failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -427,17 +459,15 @@ static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data) return ERROR_OK; } -static int cmsis_dap_cmd_DAP_LED(uint8_t led, uint8_t state) +static int cmsis_dap_cmd_dap_led(uint8_t led, uint8_t state) { - int retval; uint8_t *command = cmsis_dap_handle->command; command[0] = CMD_DAP_LED; command[1] = led; command[2] = state; - retval = cmsis_dap_xfer(cmsis_dap_handle, 3); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 3); if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { LOG_ERROR("CMSIS-DAP command CMD_LED failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -446,16 +476,14 @@ static int cmsis_dap_cmd_DAP_LED(uint8_t led, uint8_t state) return ERROR_OK; } -static int cmsis_dap_cmd_DAP_Connect(uint8_t mode) +static int cmsis_dap_cmd_dap_connect(uint8_t mode) { - int retval; uint8_t *command = cmsis_dap_handle->command; command[0] = CMD_DAP_CONNECT; command[1] = mode; - retval = cmsis_dap_xfer(cmsis_dap_handle, 2); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 2); if (retval != ERROR_OK) { LOG_ERROR("CMSIS-DAP command CMD_CONNECT failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -469,15 +497,13 @@ static int cmsis_dap_cmd_DAP_Connect(uint8_t mode) return ERROR_OK; } -static int cmsis_dap_cmd_DAP_Disconnect(void) +static int cmsis_dap_cmd_dap_disconnect(void) { - int retval; uint8_t *command = cmsis_dap_handle->command; command[0] = CMD_DAP_DISCONNECT; - retval = cmsis_dap_xfer(cmsis_dap_handle, 1); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 1); if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { LOG_ERROR("CMSIS-DAP command CMD_DISCONNECT failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -486,9 +512,8 @@ static int cmsis_dap_cmd_DAP_Disconnect(void) return ERROR_OK; } -static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t retry_count, uint16_t match_retry) +static int cmsis_dap_cmd_dap_tfer_configure(uint8_t idle, uint16_t retry_count, uint16_t match_retry) { - int retval; uint8_t *command = cmsis_dap_handle->command; command[0] = CMD_DAP_TFER_CONFIGURE; @@ -496,8 +521,7 @@ static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t retry_count, h_u16_to_le(&command[2], retry_count); h_u16_to_le(&command[4], match_retry); - retval = cmsis_dap_xfer(cmsis_dap_handle, 6); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 6); if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { LOG_ERROR("CMSIS-DAP command CMD_TFER_Configure failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -506,16 +530,14 @@ static int cmsis_dap_cmd_DAP_TFER_Configure(uint8_t idle, uint16_t retry_count, return ERROR_OK; } -static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg) +static int cmsis_dap_cmd_dap_swd_configure(uint8_t cfg) { - int retval; uint8_t *command = cmsis_dap_handle->command; command[0] = CMD_DAP_SWD_CONFIGURE; command[1] = cfg; - retval = cmsis_dap_xfer(cmsis_dap_handle, 2); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 2); if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { LOG_ERROR("CMSIS-DAP command CMD_SWD_Configure failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -525,16 +547,14 @@ static int cmsis_dap_cmd_DAP_SWD_Configure(uint8_t cfg) } #if 0 -static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us) +static int cmsis_dap_cmd_dap_delay(uint16_t delay_us) { - int retval; uint8_t *command = cmsis_dap_handle->command; command[0] = CMD_DAP_DELAY; h_u16_to_le(&command[1], delay_us); - retval = cmsis_dap_xfer(cmsis_dap_handle, 3); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, 3); if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { LOG_ERROR("CMSIS-DAP command CMD_Delay failed."); return ERROR_JTAG_DEVICE_ERROR; @@ -546,7 +566,6 @@ static int cmsis_dap_cmd_DAP_Delay(uint16_t delay_us) static int cmsis_dap_metacmd_targetsel(uint32_t instance_id) { - int retval; uint8_t *command = cmsis_dap_handle->command; const uint32_t SEQ_RD = 0x80, SEQ_WR = 0x00; @@ -574,12 +593,171 @@ static int cmsis_dap_metacmd_targetsel(uint32_t instance_id) idx += 4; command[idx++] = parity_u32(instance_id); - retval = cmsis_dap_xfer(cmsis_dap_handle, idx); - + int retval = cmsis_dap_xfer(cmsis_dap_handle, idx); if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { LOG_ERROR("CMSIS-DAP command SWD_Sequence failed."); return ERROR_JTAG_DEVICE_ERROR; } + + return ERROR_OK; +} + +/** + * Sets the SWO transport mode. + * @param[in] transport The transport mode. Can be None, SWO_Data or + * WinUSB (requires CMSIS-DAP v2). + */ +static int cmsis_dap_cmd_dap_swo_transport(uint8_t transport) +{ + uint8_t *command = cmsis_dap_handle->command; + + command[0] = CMD_DAP_SWO_TRANSPORT; + command[1] = transport; + + int retval = cmsis_dap_xfer(cmsis_dap_handle, 2); + if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { + LOG_ERROR("CMSIS-DAP: command CMD_SWO_Transport(%d) failed.", transport); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +/** + * Sets the SWO trace capture mode. + * @param[in] mode Trace capture mode. Can be UART or MANCHESTER. + */ +static int cmsis_dap_cmd_dap_swo_mode(uint8_t mode) +{ + uint8_t *command = cmsis_dap_handle->command; + + command[0] = CMD_DAP_SWO_MODE; + command[1] = mode; + + int retval = cmsis_dap_xfer(cmsis_dap_handle, 2); + if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { + LOG_ERROR("CMSIS-DAP: command CMD_SWO_Mode(%d) failed.", mode); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +/** + * Sets the baudrate for capturing SWO trace data. + * Can be called iteratively to determine supported baudrates. + * @param[in] in_baudrate Requested baudrate. + * @param[out] dev_baudrate Actual baudrate or 0 (baudrate not configured). + * When requested baudrate is not achievable the + * closest configured baudrate can be returned or + * 0 which indicates that baudrate was not configured. + */ +static int cmsis_dap_cmd_dap_swo_baudrate( + uint32_t in_baudrate, + uint32_t *dev_baudrate) +{ + uint8_t *command = cmsis_dap_handle->command; + + command[0] = CMD_DAP_SWO_BAUDRATE; + h_u32_to_le(&command[1], in_baudrate); + + int retval = cmsis_dap_xfer(cmsis_dap_handle, 4); + uint32_t rvbr = le_to_h_u32(&cmsis_dap_handle->response[1]); + if (retval != ERROR_OK || rvbr == 0) { + LOG_ERROR("CMSIS-DAP: command CMD_SWO_Baudrate(%u) -> %u failed.", in_baudrate, rvbr); + if (dev_baudrate) + *dev_baudrate = 0; + return ERROR_JTAG_DEVICE_ERROR; + } + + if (dev_baudrate) + *dev_baudrate = rvbr; + + return ERROR_OK; +} + +/** + * Controls the SWO trace data capture. + * @param[in] control Start or stop a trace. Starting capture automatically + * flushes any existing trace data in buffers which has + * not yet been read. + */ +static int cmsis_dap_cmd_dap_swo_control(uint8_t control) +{ + uint8_t *command = cmsis_dap_handle->command; + + command[0] = CMD_DAP_SWO_CONTROL; + command[1] = control; + + int retval = cmsis_dap_xfer(cmsis_dap_handle, 2); + if (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) { + LOG_ERROR("CMSIS-DAP: command CMD_SWO_Control(%d) failed.", control); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +/** + * Reads the SWO trace status. + * @param[out] trace_status The trace's status. + * Bit0: Trace Capture (1 - active, 0 - inactive). + * Bit6: Trace Stream Error. + * Bit7: Trace Buffer Overrun. + * @param[out] trace_count Number of bytes in Trace Buffer (not yet read). + */ +static int cmsis_dap_cmd_dap_swo_status( + uint8_t *trace_status, + size_t *trace_count) +{ + uint8_t *command = cmsis_dap_handle->command; + + command[0] = CMD_DAP_SWO_STATUS; + + int retval = cmsis_dap_xfer(cmsis_dap_handle, 1); + if (retval != ERROR_OK) { + LOG_ERROR("CMSIS-DAP: command CMD_SWO_Status failed."); + return ERROR_JTAG_DEVICE_ERROR; + } + + if (trace_status) + *trace_status = cmsis_dap_handle->response[1]; + if (trace_count) + *trace_count = le_to_h_u32(&cmsis_dap_handle->response[2]); + + return ERROR_OK; +} + +/** + * Reads the captured SWO trace data from Trace Buffer. + * @param[in] max_trace_count Maximum number of Trace Data bytes to read. + * @param[out] trace_status The trace's status. + * @param[out] trace_count Number of Trace Data bytes read. + * @param[out] data Trace Data bytes read. + */ +static int cmsis_dap_cmd_dap_swo_data( + size_t max_trace_count, + uint8_t *trace_status, + size_t *trace_count, + uint8_t *data) +{ + uint8_t *command = cmsis_dap_handle->command; + + command[0] = CMD_DAP_SWO_DATA; + h_u16_to_le(&command[1], max_trace_count); + + int retval = cmsis_dap_xfer(cmsis_dap_handle, 3); + if (retval != ERROR_OK) { + LOG_ERROR("CMSIS-DAP: command CMD_SWO_Data failed."); + return ERROR_JTAG_DEVICE_ERROR; + } + + *trace_status = cmsis_dap_handle->response[1]; + *trace_count = le_to_h_u16(&cmsis_dap_handle->response[2]); + + if (*trace_count > 0) + memcpy(data, &cmsis_dap_handle->response[4], *trace_count); + return ERROR_OK; } @@ -620,8 +798,8 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) * able to automatically retry anything (because ARM * has forgotten to implement sticky error flags * clearing). See also comments regarding - * cmsis_dap_cmd_DAP_TFER_Configure() and - * cmsis_dap_cmd_DAP_SWD_Configure() in + * cmsis_dap_cmd_dap_tfer_configure() and + * cmsis_dap_cmd_dap_swd_configure() in * cmsis_dap_init(). */ if (!(cmd & SWD_CMD_RnW) && @@ -640,7 +818,6 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap) } int retval = dap->backend->write(dap, idx, USB_TIMEOUT); - if (retval < 0) { queued_retval = retval; goto skip; @@ -679,8 +856,8 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms) uint8_t *resp = dap->response; if (resp[0] != CMD_DAP_TFER) { - LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%" PRIx8 - " received 0x%" PRIx8, CMD_DAP_TFER, resp[0]); + LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%x received 0x%" PRIx8, + CMD_DAP_TFER, resp[0]); queued_retval = ERROR_FAIL; goto skip; } @@ -805,7 +982,7 @@ static int cmsis_dap_get_serial_info(void) { uint8_t *data; - int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_SERNUM, &data); + int retval = cmsis_dap_cmd_dap_info(INFO_ID_SERNUM, &data); if (retval != ERROR_OK) return retval; @@ -820,7 +997,7 @@ static int cmsis_dap_get_version_info(void) uint8_t *data; /* INFO_ID_FW_VER - string */ - int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_FW_VER, &data); + int retval = cmsis_dap_cmd_dap_info(INFO_ID_FW_VER, &data); if (retval != ERROR_OK) return retval; @@ -835,7 +1012,7 @@ static int cmsis_dap_get_caps_info(void) uint8_t *data; /* INFO_ID_CAPS - byte */ - int retval = cmsis_dap_cmd_DAP_Info(INFO_ID_CAPS, &data); + int retval = cmsis_dap_cmd_dap_info(INFO_ID_CAPS, &data); if (retval != ERROR_OK) return retval; @@ -848,16 +1025,39 @@ static int cmsis_dap_get_caps_info(void) LOG_INFO("CMSIS-DAP: %s", info_caps_str[0]); if (caps & INFO_CAPS_JTAG) LOG_INFO("CMSIS-DAP: %s", info_caps_str[1]); + if (caps & INFO_CAPS_SWO_UART) + LOG_INFO("CMSIS-DAP: %s", info_caps_str[2]); + if (caps & INFO_CAPS_SWO_MANCHESTER) + LOG_INFO("CMSIS-DAP: %s", info_caps_str[3]); } return ERROR_OK; } +static int cmsis_dap_get_swo_buf_sz(uint32_t *swo_buf_sz) +{ + uint8_t *data; + + /* INFO_ID_SWO_BUF_SZ - word */ + int retval = cmsis_dap_cmd_dap_info(INFO_ID_SWO_BUF_SZ, &data); + if (retval != ERROR_OK) + return retval; + + if (data[0] != 4) + return ERROR_FAIL; + + *swo_buf_sz = le_to_h_u32(&data[1]); + + LOG_INFO("CMSIS-DAP: SWO Trace Buffer Size = %u bytes", *swo_buf_sz); + + return ERROR_OK; +} + static int cmsis_dap_get_status(void) { uint8_t d; - int retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, 0, 0, &d); + int retval = cmsis_dap_cmd_dap_swj_pins(0, 0, 0, &d); if (retval == ERROR_OK) { LOG_INFO("SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d", @@ -884,11 +1084,11 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq) * Reconnecting would break connecting under reset. */ /* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */ - cmsis_dap_cmd_DAP_Disconnect(); + cmsis_dap_cmd_dap_disconnect(); /* When we are reconnecting, DAP_Connect needs to be rerun, at * least on Keil ULINK-ME */ - retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD); + retval = cmsis_dap_cmd_dap_connect(CONNECT_SWD); if (retval != ERROR_OK) return retval; } @@ -929,25 +1129,23 @@ static int cmsis_dap_swd_switch_seq(enum swd_special_seq seq) return ERROR_FAIL; } - retval = cmsis_dap_cmd_DAP_SWJ_Sequence(s_len, s); + retval = cmsis_dap_cmd_dap_swj_sequence(s_len, s); if (retval != ERROR_OK) return retval; /* Atmel EDBG needs renew clock setting after SWJ_Sequence * otherwise default frequency is used */ - return cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz()); + return cmsis_dap_cmd_dap_swj_clock(jtag_get_speed_khz()); } static int cmsis_dap_swd_open(void) { - int retval; - if (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) { LOG_ERROR("CMSIS-DAP: SWD not supported"); return ERROR_JTAG_DEVICE_ERROR; } - retval = cmsis_dap_cmd_DAP_Connect(CONNECT_SWD); + int retval = cmsis_dap_cmd_dap_connect(CONNECT_SWD); if (retval != ERROR_OK) return retval; @@ -959,10 +1157,9 @@ static int cmsis_dap_swd_open(void) static int cmsis_dap_init(void) { - int retval; uint8_t *data; - retval = cmsis_dap_open(); + int retval = cmsis_dap_open(); if (retval != ERROR_OK) return retval; @@ -991,7 +1188,7 @@ static int cmsis_dap_init(void) return ERROR_JTAG_DEVICE_ERROR; } - retval = cmsis_dap_cmd_DAP_Connect(CONNECT_JTAG); + retval = cmsis_dap_cmd_dap_connect(CONNECT_JTAG); if (retval != ERROR_OK) return retval; @@ -1004,7 +1201,7 @@ static int cmsis_dap_init(void) pending_queue_len = 12; /* INFO_ID_PKT_SZ - short */ - retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_SZ, &data); + retval = cmsis_dap_cmd_dap_info(INFO_ID_PKT_SZ, &data); if (retval != ERROR_OK) goto init_err; @@ -1027,7 +1224,7 @@ static int cmsis_dap_init(void) } /* INFO_ID_PKT_CNT - byte */ - retval = cmsis_dap_cmd_DAP_Info(INFO_ID_PKT_CNT, &data); + retval = cmsis_dap_cmd_dap_info(INFO_ID_PKT_CNT, &data); if (retval != ERROR_OK) goto init_err; @@ -1055,36 +1252,36 @@ static int cmsis_dap_init(void) /* Now try to connect to the target * TODO: This is all SWD only @ present */ - retval = cmsis_dap_cmd_DAP_SWJ_Clock(jtag_get_speed_khz()); + retval = cmsis_dap_cmd_dap_swj_clock(jtag_get_speed_khz()); if (retval != ERROR_OK) goto init_err; /* Ask CMSIS-DAP to automatically retry on receiving WAIT for * up to 64 times. This must be changed to 0 if sticky * overrun detection is enabled. */ - retval = cmsis_dap_cmd_DAP_TFER_Configure(0, 64, 0); + retval = cmsis_dap_cmd_dap_tfer_configure(0, 64, 0); if (retval != ERROR_OK) goto init_err; if (swd_mode) { /* Data Phase (bit 2) must be set to 1 if sticky overrun * detection is enabled */ - retval = cmsis_dap_cmd_DAP_SWD_Configure(0); /* 1 TRN, no Data Phase */ + retval = cmsis_dap_cmd_dap_swd_configure(0); /* 1 TRN, no Data Phase */ if (retval != ERROR_OK) goto init_err; } /* Both LEDs on */ /* Intentionally not checked for error, debugging will work * without LEDs */ - (void)cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_ON); - (void)cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_ON); + (void)cmsis_dap_cmd_dap_led(LED_ID_CONNECT, LED_ON); + (void)cmsis_dap_cmd_dap_led(LED_ID_RUN, LED_ON); /* support connecting with srst asserted */ enum reset_types jtag_reset_config = jtag_get_reset_config(); if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { if (jtag_reset_config & RESET_SRST_NO_GATING) { - retval = cmsis_dap_cmd_DAP_SWJ_Pins(0, SWJ_PIN_SRST, 0, NULL); + retval = cmsis_dap_cmd_dap_swj_pins(0, SWJ_PIN_SRST, 0, NULL); if (retval != ERROR_OK) goto init_err; LOG_INFO("Connecting under reset"); @@ -1106,10 +1303,11 @@ static int cmsis_dap_swd_init(void) static int cmsis_dap_quit(void) { - cmsis_dap_cmd_DAP_Disconnect(); + cmsis_dap_cmd_dap_disconnect(); + /* Both LEDs off */ - cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_OFF); - cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_OFF); + cmsis_dap_cmd_dap_led(LED_ID_RUN, LED_OFF); + cmsis_dap_cmd_dap_led(LED_ID_CONNECT, LED_OFF); cmsis_dap_close(cmsis_dap_handle); @@ -1127,7 +1325,7 @@ static int cmsis_dap_reset(int trst, int srst) if (!trst) output_pins |= SWJ_PIN_TRST; - int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins, + int retval = cmsis_dap_cmd_dap_swj_pins(output_pins, SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL); if (retval != ERROR_OK) LOG_ERROR("CMSIS-DAP: Interface reset failed"); @@ -1137,7 +1335,7 @@ static int cmsis_dap_reset(int trst, int srst) static void cmsis_dap_execute_sleep(struct jtag_command *cmd) { #if 0 - int retval = cmsis_dap_cmd_DAP_Delay(cmd->cmd.sleep->us); + int retval = cmsis_dap_cmd_dap_delay(cmd->cmd.sleep->us); if (retval != ERROR_OK) #endif jtag_sleep(cmd->cmd.sleep->us); @@ -1148,10 +1346,11 @@ static int cmsis_dap_execute_tlr_reset(struct jtag_command *cmd) { LOG_INFO("cmsis-dap JTAG TLR_RESET"); uint8_t seq = 0xff; - int ret = cmsis_dap_cmd_DAP_SWJ_Sequence(8, &seq); - if (ret == ERROR_OK) + + int retval = cmsis_dap_cmd_dap_swj_sequence(8, &seq); + if (retval == ERROR_OK) tap_set_state(TAP_RESET); - return ret; + return retval; } /* Set new end state */ @@ -1369,11 +1568,8 @@ static void cmsis_dap_add_tms_sequence(const uint8_t *sequence, int s_len) /* Move to the end state by queuing a sequence to clock into TMS */ static void cmsis_dap_state_move(void) { - uint8_t tms_scan; - uint8_t tms_scan_bits; - - tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); - tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); + uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state()); + uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state()); LOG_DEBUG_IO("state move from %s to %s: %d clocks, %02X on tms", tap_state_name(tap_get_state()), tap_state_name(tap_get_end_state()), @@ -1488,11 +1684,10 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd) static void cmsis_dap_pathmove(int num_states, tap_state_t *path) { - int i; uint8_t tms0 = 0x00; uint8_t tms1 = 0xff; - for (i = 0; i < num_states; i++) { + for (int i = 0; i < num_states; i++) { if (path[i] == tap_state_transition(tap_get_state(), false)) cmsis_dap_add_tms_sequence(&tms0, 1); else if (path[i] == tap_state_transition(tap_get_state(), true)) @@ -1520,12 +1715,10 @@ static void cmsis_dap_execute_pathmove(struct jtag_command *cmd) static void cmsis_dap_stableclocks(int num_cycles) { - int i; - uint8_t tms = tap_get_state() == TAP_RESET; /* TODO: Perform optimizations? */ /* Execute num_cycles. */ - for (i = 0; i < num_cycles; i++) + for (int i = 0; i < num_cycles; i++) cmsis_dap_add_tms_sequence(&tms, 1); } @@ -1565,7 +1758,7 @@ static void cmsis_dap_execute_stableclocks(struct jtag_command *cmd) static void cmsis_dap_execute_tms(struct jtag_command *cmd) { LOG_DEBUG_IO("TMS: %d bits", cmd->cmd.tms->num_bits); - cmsis_dap_cmd_DAP_SWJ_Sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits); + cmsis_dap_cmd_dap_swj_sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits); } /* TODO: Is there need to call cmsis_dap_flush() for the JTAG_PATHMOVE, @@ -1623,7 +1816,7 @@ static int cmsis_dap_speed(int speed) return ERROR_JTAG_NOT_IMPLEMENTED; } - return cmsis_dap_cmd_DAP_SWJ_Clock(speed); + return cmsis_dap_cmd_dap_swj_clock(speed); } static int cmsis_dap_speed_div(int speed, int *khz) @@ -1638,6 +1831,157 @@ static int cmsis_dap_khz(int khz, int *jtag_speed) return ERROR_OK; } +static bool calculate_swo_prescaler(unsigned int traceclkin_freq, + uint32_t trace_freq, uint16_t *prescaler) +{ + unsigned int presc = (traceclkin_freq + trace_freq / 2) / trace_freq; + if (presc == 0 || presc > TPIU_ACPR_MAX_SWOSCALER + 1) + return false; + + /* Probe's UART speed must be within 3% of the TPIU's SWO baud rate. */ + unsigned int max_deviation = (traceclkin_freq * 3) / 100; + if (presc * trace_freq < traceclkin_freq - max_deviation || + presc * trace_freq > traceclkin_freq + max_deviation) + return false; + + *prescaler = presc; + + return true; +} + +/** + * @see adapter_driver::config_trace + */ +static int cmsis_dap_config_trace( + bool trace_enabled, + enum tpiu_pin_protocol pin_protocol, + uint32_t port_size, + unsigned int *swo_freq, + unsigned int traceclkin_hz, + uint16_t *swo_prescaler) +{ + int retval; + + if (!trace_enabled) { + if (cmsis_dap_handle->trace_enabled) { + retval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_STOP); + if (retval != ERROR_OK) { + LOG_ERROR("Failed to disable the SWO-trace."); + return retval; + } + } + cmsis_dap_handle->trace_enabled = false; + LOG_INFO("SWO-trace disabled."); + return ERROR_OK; + } + + if (!(cmsis_dap_handle->caps & INFO_CAPS_SWO_UART) && + !(cmsis_dap_handle->caps & INFO_CAPS_SWO_MANCHESTER)) { + LOG_ERROR("SWO-trace is not supported by the device."); + return ERROR_FAIL; + } + + uint8_t swo_mode; + if (pin_protocol == TPIU_PIN_PROTOCOL_ASYNC_UART && + (cmsis_dap_handle->caps & INFO_CAPS_SWO_UART)) { + swo_mode = DAP_SWO_MODE_UART; + } else if (pin_protocol == TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER && + (cmsis_dap_handle->caps & INFO_CAPS_SWO_MANCHESTER)) { + swo_mode = DAP_SWO_MODE_MANCHESTER; + } else { + LOG_ERROR("Selected pin protocol is not supported."); + return ERROR_FAIL; + } + + if (*swo_freq == 0) { + LOG_INFO("SWO-trace frequency autodetection not implemented."); + return ERROR_FAIL; + } + + retval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_STOP); + if (retval != ERROR_OK) + return retval; + + cmsis_dap_handle->trace_enabled = false; + + retval = cmsis_dap_get_swo_buf_sz(&cmsis_dap_handle->swo_buf_sz); + if (retval != ERROR_OK) + return retval; + + retval = cmsis_dap_cmd_dap_swo_transport(DAP_SWO_TRANSPORT_DATA); + if (retval != ERROR_OK) + return retval; + + retval = cmsis_dap_cmd_dap_swo_mode(swo_mode); + if (retval != ERROR_OK) + return retval; + + retval = cmsis_dap_cmd_dap_swo_baudrate(*swo_freq, swo_freq); + if (retval != ERROR_OK) + return retval; + + if (!calculate_swo_prescaler(traceclkin_hz, *swo_freq, + swo_prescaler)) { + LOG_ERROR("SWO frequency is not suitable. Please choose a " + "different frequency or use auto-detection."); + return ERROR_FAIL; + } + + LOG_INFO("SWO frequency: %u Hz.", *swo_freq); + LOG_INFO("SWO prescaler: %u.", *swo_prescaler); + + retval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_START); + if (retval != ERROR_OK) + return retval; + + cmsis_dap_handle->trace_enabled = true; + + return ERROR_OK; +} + +/** + * @see adapter_driver::poll_trace + */ +static int cmsis_dap_poll_trace(uint8_t *buf, size_t *size) +{ + uint8_t trace_status; + size_t trace_count; + + if (!cmsis_dap_handle->trace_enabled) { + *size = 0; + return ERROR_OK; + } + + int retval = cmsis_dap_cmd_dap_swo_status(&trace_status, &trace_count); + if (retval != ERROR_OK) + return retval; + if ((trace_status & DAP_SWO_STATUS_CAPTURE_MASK) != DAP_SWO_STATUS_CAPTURE_ACTIVE) + return ERROR_FAIL; + + *size = trace_count < *size ? trace_count : *size; + size_t read_so_far = 0; + do { + size_t rb = 0; + uint32_t packet_size = cmsis_dap_handle->packet_size - 4 /*data-reply*/; + uint32_t remaining = *size - read_so_far; + if (remaining < packet_size) + packet_size = remaining; + retval = cmsis_dap_cmd_dap_swo_data( + packet_size, + &trace_status, + &rb, + &buf[read_so_far]); + if (retval != ERROR_OK) + return retval; + if ((trace_status & DAP_SWO_STATUS_CAPTURE_MASK) != DAP_SWO_STATUS_CAPTURE_ACTIVE) + return ERROR_FAIL; + + read_so_far += rb; + } while (read_so_far < *size); + + return ERROR_OK; +} + COMMAND_HANDLER(cmsis_dap_handle_info_command) { if (cmsis_dap_get_version_info() == ERROR_OK) @@ -1648,14 +1992,12 @@ COMMAND_HANDLER(cmsis_dap_handle_info_command) COMMAND_HANDLER(cmsis_dap_handle_cmd_command) { - int retval; - unsigned i; uint8_t *command = cmsis_dap_handle->command; - for (i = 0; i < CMD_ARGC; i++) + for (unsigned i = 0; i < CMD_ARGC; i++) command[i] = strtoul(CMD_ARGV[i], NULL, 16); - retval = cmsis_dap_xfer(cmsis_dap_handle, CMD_ARGC); + int retval = cmsis_dap_xfer(cmsis_dap_handle, CMD_ARGC); if (retval != ERROR_OK) { LOG_ERROR("CMSIS-DAP command failed."); @@ -1763,7 +2105,7 @@ static const struct command_registration cmsis_dap_command_handlers[] = { .handler = &cmsis_dap_handle_vid_pid_command, .mode = COMMAND_CONFIG, .help = "the vendor ID and product ID of the CMSIS-DAP device", - .usage = "(vid pid)* ", + .usage = "(vid pid)*", }, { .name = "cmsis_dap_serial", @@ -1817,6 +2159,8 @@ struct adapter_driver cmsis_dap_adapter_driver = { .speed = cmsis_dap_speed, .khz = cmsis_dap_khz, .speed_div = cmsis_dap_speed_div, + .config_trace = cmsis_dap_config_trace, + .poll_trace = cmsis_dap_poll_trace, .jtag_ops = &cmsis_dap_interface, .swd_ops = &cmsis_dap_swd_driver, diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h index c9f24c8..634a62c 100644 --- a/src/jtag/drivers/cmsis_dap.h +++ b/src/jtag/drivers/cmsis_dap.h @@ -18,6 +18,8 @@ struct cmsis_dap { uint8_t *response; uint8_t caps; uint8_t mode; + uint32_t swo_buf_sz; + bool trace_enabled; }; struct cmsis_dap_backend { diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c index a588b1b..c42bab2 100644 --- a/src/jtag/drivers/cmsis_dap_usb_bulk.c +++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c @@ -262,7 +262,7 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p * - config asked explicitly for an interface number * - the device has only one interface * The later two cases should be honored only if we know - * we are on the rigt device */ + * we are on the right device */ bool intf_identified_reliably = cmsis_dap_in_interface_str || (device_identified_reliably && (cmsis_dap_usb_interface != -1 diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 457fc2f..682f27f 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -1253,22 +1253,22 @@ COMMAND_HANDLER(ftdi_handle_vid_pid_command) COMMAND_HANDLER(ftdi_handle_tdo_sample_edge_command) { - Jim_Nvp *n; - static const Jim_Nvp nvp_ftdi_jtag_modes[] = { + struct jim_nvp *n; + static const struct jim_nvp nvp_ftdi_jtag_modes[] = { { .name = "rising", .value = JTAG_MODE }, { .name = "falling", .value = JTAG_MODE_ALT }, { .name = NULL, .value = -1 }, }; if (CMD_ARGC > 0) { - n = Jim_Nvp_name2value_simple(nvp_ftdi_jtag_modes, CMD_ARGV[0]); + n = jim_nvp_name2value_simple(nvp_ftdi_jtag_modes, CMD_ARGV[0]); if (n->name == NULL) return ERROR_COMMAND_SYNTAX_ERROR; ftdi_jtag_mode = n->value; } - n = Jim_Nvp_value2name_simple(nvp_ftdi_jtag_modes, ftdi_jtag_mode); + n = jim_nvp_value2name_simple(nvp_ftdi_jtag_modes, ftdi_jtag_mode); command_print(CMD, "ftdi samples TDO on %s edge of TCK", n->name); return ERROR_OK; @@ -1345,7 +1345,7 @@ static const struct command_registration ftdi_command_handlers[] = { .handler = &ftdi_handle_vid_pid_command, .mode = COMMAND_CONFIG, .help = "the vendor ID and product ID of the FTDI device", - .usage = "(vid pid)* ", + .usage = "(vid pid)*", }, { .name = "ftdi_tdo_sample_edge", diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 8c1a811..6781e14 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -282,7 +282,7 @@ static int jlink_execute_command(struct jtag_command *cmd) jlink_execute_sleep(cmd); break; default: - LOG_ERROR("BUG: Unknown JTAG command type encountered."); + LOG_ERROR("BUG: Unknown JTAG command type encountered"); return ERROR_JTAG_QUEUE_FAILED; } @@ -316,7 +316,7 @@ static int jlink_speed(int speed) ret = jaylink_get_speeds(devh, &tmp); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_speeds() failed: %s.", + LOG_ERROR("jaylink_get_speeds() failed: %s", jaylink_strerror(ret)); return ERROR_JTAG_DEVICE_ERROR; } @@ -329,13 +329,13 @@ static int jlink_speed(int speed) if (!speed) { if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ADAPTIVE_CLOCKING)) { - LOG_ERROR("Adaptive clocking is not supported by the device."); + LOG_ERROR("Adaptive clocking is not supported by the device"); return ERROR_JTAG_NOT_IMPLEMENTED; } speed = JAYLINK_SPEED_ADAPTIVE_CLOCKING; } else if (speed > max_speed) { - LOG_INFO("Reduced speed from %d kHz to %d kHz (maximum).", speed, + LOG_INFO("Reduced speed from %d kHz to %d kHz (maximum)", speed, max_speed); speed = max_speed; } @@ -343,7 +343,7 @@ static int jlink_speed(int speed) ret = jaylink_set_speed(devh, speed); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_set_speed() failed: %s.", + LOG_ERROR("jaylink_set_speed() failed: %s", jaylink_strerror(ret)); return ERROR_JTAG_DEVICE_ERROR; } @@ -372,7 +372,7 @@ static bool read_device_config(struct device_config *cfg) ret = jaylink_read_raw_config(devh, (uint8_t *)cfg); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_read_raw_config() failed: %s.", + LOG_ERROR("jaylink_read_raw_config() failed: %s", jaylink_strerror(ret)); return false; } @@ -393,7 +393,7 @@ static int select_interface(void) if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SELECT_TIF)) { if (iface != JAYLINK_TIF_JTAG) { - LOG_ERROR("Device supports JTAG transport only."); + LOG_ERROR("Device supports JTAG transport only"); return ERROR_JTAG_INIT_FAILED; } @@ -403,20 +403,20 @@ static int select_interface(void) ret = jaylink_get_available_interfaces(devh, &interfaces); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_available_interfaces() failed: %s.", + LOG_ERROR("jaylink_get_available_interfaces() failed: %s", jaylink_strerror(ret)); return ERROR_JTAG_INIT_FAILED; } if (!(interfaces & (1 << iface))) { - LOG_ERROR("Selected transport is not supported by the device."); + LOG_ERROR("Selected transport is not supported by the device"); return ERROR_JTAG_INIT_FAILED; } ret = jaylink_select_interface(devh, iface, NULL); if (ret < 0) { - LOG_ERROR("jaylink_select_interface() failed: %s.", + LOG_ERROR("jaylink_select_interface() failed: %s", jaylink_strerror(ret)); return ERROR_JTAG_INIT_FAILED; } @@ -437,7 +437,7 @@ static int jlink_register(void) ret = jaylink_register(devh, &conn, connlist, &count); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_register() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_register() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -452,7 +452,7 @@ static int jlink_register(void) if (!handle_found) { LOG_ERROR("Registration failed: maximum number of connections on the " - "device reached."); + "device reached"); return ERROR_FAIL; } @@ -475,13 +475,13 @@ static bool adjust_swd_buffer_size(void) ret = jaylink_get_free_memory(devh, &tmp); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_free_memory() failed: %s.", + LOG_ERROR("jaylink_get_free_memory() failed: %s", jaylink_strerror(ret)); return false; } if (tmp < 143) { - LOG_ERROR("Not enough free device internal memory: %" PRIu32 " bytes.", tmp); + LOG_ERROR("Not enough free device internal memory: %" PRIu32 " bytes", tmp); return false; } @@ -489,7 +489,7 @@ static bool adjust_swd_buffer_size(void) if (tmp != swd_buffer_size) { swd_buffer_size = tmp; - LOG_DEBUG("Adjusted SWD transaction buffer size to %u bytes.", + LOG_DEBUG("Adjusted SWD transaction buffer size to %u bytes", swd_buffer_size); } @@ -542,7 +542,7 @@ static bool jlink_usb_location_equal(struct jaylink_device *dev) if (retval == JAYLINK_ERR_NOT_SUPPORTED) { return false; } else if (retval != JAYLINK_OK) { - LOG_WARNING("jaylink_device_get_usb_bus_ports() failed: %s.", + LOG_WARNING("jaylink_device_get_usb_bus_ports() failed: %s", jaylink_strerror(retval)); return false; } @@ -558,7 +558,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device) { int ret = jaylink_discovery_scan(jayctx, ifaces); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_discovery_scan() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_discovery_scan() failed: %s", jaylink_strerror(ret)); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } @@ -568,7 +568,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device) ret = jaylink_get_devices(jayctx, &devs, &num_devices); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_devices() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_get_devices() failed: %s", jaylink_strerror(ret)); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } @@ -576,7 +576,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device) use_usb_location = (jtag_usb_get_location() != NULL); if (!use_serial_number && !use_usb_address && !use_usb_location && num_devices > 1) { - LOG_ERROR("Multiple devices found, specify the desired device."); + LOG_ERROR("Multiple devices found, specify the desired device"); jaylink_free_devices(devs, true); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; @@ -594,7 +594,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device) if (ret == JAYLINK_ERR_NOT_AVAILABLE) { continue; } else if (ret != JAYLINK_OK) { - LOG_WARNING("jaylink_device_get_serial_number() failed: %s.", + LOG_WARNING("jaylink_device_get_serial_number() failed: %s", jaylink_strerror(ret)); continue; } @@ -610,7 +610,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device) if (ret == JAYLINK_ERR_NOT_SUPPORTED) { continue; } else if (ret != JAYLINK_OK) { - LOG_WARNING("jaylink_device_get_usb_address() failed: %s.", + LOG_WARNING("jaylink_device_get_usb_address() failed: %s", jaylink_strerror(ret)); continue; } @@ -629,7 +629,7 @@ static int jlink_open_device(uint32_t ifaces, bool *found_device) break; } - LOG_ERROR("Failed to open device: %s.", jaylink_strerror(ret)); + LOG_ERROR("Failed to open device: %s", jaylink_strerror(ret)); } jaylink_free_devices(devs, true); @@ -645,25 +645,25 @@ static int jlink_init(void) struct jaylink_hardware_status hwstatus; size_t length; - LOG_DEBUG("Using libjaylink %s (compiled with %s).", + LOG_DEBUG("Using libjaylink %s (compiled with %s)", jaylink_version_package_get_string(), JAYLINK_VERSION_PACKAGE_STRING); if (!jaylink_library_has_cap(JAYLINK_CAP_HIF_USB) && use_usb_address) { - LOG_ERROR("J-Link driver does not support USB devices."); + LOG_ERROR("J-Link driver does not support USB devices"); return ERROR_JTAG_INIT_FAILED; } ret = jaylink_init(&jayctx); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_init() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_init() failed: %s", jaylink_strerror(ret)); return ERROR_JTAG_INIT_FAILED; } ret = jaylink_log_set_callback(jayctx, &jaylink_log_handler, NULL); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_log_set_callback() failed: %s.", + LOG_ERROR("jaylink_log_set_callback() failed: %s", jaylink_strerror(ret)); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; @@ -681,7 +681,7 @@ static int jlink_init(void) } if (!found_device) { - LOG_ERROR("No J-Link device found."); + LOG_ERROR("No J-Link device found"); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; } @@ -694,7 +694,7 @@ static int jlink_init(void) ret = jaylink_get_firmware_version(devh, &firmware_version, &length); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_firmware_version() failed: %s.", + LOG_ERROR("jaylink_get_firmware_version() failed: %s", jaylink_strerror(ret)); jaylink_close(devh); jaylink_exit(jayctx); @@ -703,14 +703,14 @@ static int jlink_init(void) LOG_INFO("%s", firmware_version); free(firmware_version); } else { - LOG_WARNING("Device responds empty firmware version string."); + LOG_WARNING("Device responds empty firmware version string"); } memset(caps, 0, JAYLINK_DEV_EXT_CAPS_SIZE); ret = jaylink_get_caps(devh, caps); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_caps() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_get_caps() failed: %s", jaylink_strerror(ret)); jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; @@ -720,7 +720,7 @@ static int jlink_init(void) ret = jaylink_get_extended_caps(devh, caps); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_extended_caps() failed: %s.", + LOG_ERROR("jaylink_get_extended_caps() failed: %s", jaylink_strerror(ret)); jaylink_close(devh); jaylink_exit(jayctx); @@ -734,7 +734,7 @@ static int jlink_init(void) ret = jaylink_get_hardware_version(devh, &hwver); if (ret != JAYLINK_OK) { - LOG_ERROR("Failed to retrieve hardware version: %s.", + LOG_ERROR("Failed to retrieve hardware version: %s", jaylink_strerror(ret)); jaylink_close(devh); jaylink_exit(jayctx); @@ -763,7 +763,7 @@ static int jlink_init(void) if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { if (!read_device_config(&config)) { - LOG_ERROR("Failed to read device configuration data."); + LOG_ERROR("Failed to read device configuration data"); jaylink_close(devh); jaylink_exit(jayctx); return ERROR_JTAG_INIT_FAILED; @@ -775,7 +775,7 @@ static int jlink_init(void) ret = jaylink_get_hardware_status(devh, &hwstatus); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_hardware_status() failed: %s.", + LOG_ERROR("jaylink_get_hardware_status() failed: %s", jaylink_strerror(ret)); jaylink_close(devh); jaylink_exit(jayctx); @@ -837,14 +837,14 @@ static int jlink_quit(void) ret = jaylink_swo_stop(devh); if (ret != JAYLINK_OK) - LOG_ERROR("jaylink_swo_stop() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_swo_stop() failed: %s", jaylink_strerror(ret)); } if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) { ret = jaylink_unregister(devh, &conn, connlist, &count); if (ret != JAYLINK_OK) - LOG_ERROR("jaylink_unregister() failed: %s.", + LOG_ERROR("jaylink_unregister() failed: %s", jaylink_strerror(ret)); } @@ -892,7 +892,7 @@ static void jlink_path_move(int num_states, tap_state_t *path) else if (path[i] == tap_state_transition(tap_get_state(), true)) jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1); else { - LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition.", + LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(tap_get_state()), tap_state_name(path[i])); exit(-1); } @@ -935,7 +935,7 @@ static void jlink_runtest(int num_cycles) static void jlink_reset(int trst, int srst) { - LOG_DEBUG("TRST: %i, SRST: %i.", trst, srst); + LOG_DEBUG("TRST: %i, SRST: %i", trst, srst); /* Signals are active low. */ if (srst == 0) @@ -963,17 +963,17 @@ COMMAND_HANDLER(jlink_usb_command) int tmp; if (CMD_ARGC != 1) { - command_print(CMD, "Need exactly one argument for jlink usb."); + command_print(CMD, "Need exactly one argument for jlink usb"); return ERROR_COMMAND_SYNTAX_ERROR; } if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) { - command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]); return ERROR_FAIL; } if (tmp < JAYLINK_USB_ADDRESS_0 || tmp > JAYLINK_USB_ADDRESS_3) { - command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]); return ERROR_FAIL; } @@ -990,17 +990,17 @@ COMMAND_HANDLER(jlink_serial_command) int ret; if (CMD_ARGC != 1) { - command_print(CMD, "Need exactly one argument for jlink serial."); + command_print(CMD, "Need exactly one argument for jlink serial"); return ERROR_COMMAND_SYNTAX_ERROR; } ret = jaylink_parse_serial_number(CMD_ARGV[0], &serial_number); if (ret == JAYLINK_ERR) { - command_print(CMD, "Invalid serial number: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid serial number: %s", CMD_ARGV[0]); return ERROR_FAIL; } else if (ret != JAYLINK_OK) { - command_print(CMD, "jaylink_parse_serial_number() failed: %s.", + command_print(CMD, "jaylink_parse_serial_number() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -1019,7 +1019,7 @@ COMMAND_HANDLER(jlink_handle_hwstatus_command) ret = jaylink_get_hardware_status(devh, &status); if (ret != JAYLINK_OK) { - command_print(CMD, "jaylink_get_hardware_status() failed: %s.", + command_print(CMD, "jaylink_get_hardware_status() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -1032,7 +1032,7 @@ COMMAND_HANDLER(jlink_handle_hwstatus_command) status.tres, status.trst); if (status.target_voltage < 1500) - command_print(CMD, "Target voltage too low. Check target power."); + command_print(CMD, "Target voltage too low. Check target power"); return ERROR_OK; } @@ -1044,19 +1044,19 @@ COMMAND_HANDLER(jlink_handle_free_memory_command) if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY)) { command_print(CMD, "Retrieval of free memory is not supported by " - "the device."); + "the device"); return ERROR_OK; } ret = jaylink_get_free_memory(devh, &tmp); if (ret != JAYLINK_OK) { - command_print(CMD, "jaylink_get_free_memory() failed: %s.", + command_print(CMD, "jaylink_get_free_memory() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } - command_print(CMD, "Device has %" PRIu32 " bytes of free memory.", tmp); + command_print(CMD, "Device has %" PRIu32 " bytes of free memory", tmp); return ERROR_OK; } @@ -1081,7 +1081,7 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command) command_print(CMD, "JTAG command version: %i", version); } else if (CMD_ARGC == 1) { if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) { - command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1093,11 +1093,11 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command) jtag_command_version = JAYLINK_JTAG_VERSION_3; break; default: - command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]); return ERROR_COMMAND_SYNTAX_ERROR; } } else { - command_print(CMD, "Need exactly one argument for jlink jtag."); + command_print(CMD, "Need exactly one argument for jlink jtag"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1110,14 +1110,13 @@ COMMAND_HANDLER(jlink_handle_target_power_command) int enable; if (CMD_ARGC != 1) { - command_print(CMD, "Need exactly one argument for jlink " - "targetpower."); + command_print(CMD, "Need exactly one argument for jlink targetpower"); return ERROR_COMMAND_SYNTAX_ERROR; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) { command_print(CMD, "Target power supply is not supported by the " - "device."); + "device"); return ERROR_OK; } @@ -1126,14 +1125,14 @@ COMMAND_HANDLER(jlink_handle_target_power_command) } else if (!strcmp(CMD_ARGV[0], "off")) { enable = false; } else { - command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]); return ERROR_FAIL; } ret = jaylink_set_target_power(devh, enable); if (ret != JAYLINK_OK) { - command_print(CMD, "jaylink_set_target_power() failed: %s.", + command_print(CMD, "jaylink_set_target_power() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -1240,7 +1239,7 @@ static int poll_trace(uint8_t *buf, size_t *size) ret = jaylink_swo_read(devh, buf, &length); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_swo_read() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_swo_read() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -1260,7 +1259,7 @@ static uint32_t calculate_trace_buffer_size(void) ret = jaylink_get_free_memory(devh, &tmp); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_get_free_memory() failed: %s.", + LOG_ERROR("jaylink_get_free_memory() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -1334,14 +1333,14 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, if (!enabled) return ERROR_OK; - LOG_ERROR("Trace capturing is not supported by the device."); + LOG_ERROR("Trace capturing is not supported by the device"); return ERROR_FAIL; } ret = jaylink_swo_stop(devh); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_swo_stop() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_swo_stop() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -1357,21 +1356,21 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, } if (pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART) { - LOG_ERROR("Selected pin protocol is not supported."); + LOG_ERROR("Selected pin protocol is not supported"); return ERROR_FAIL; } buffer_size = calculate_trace_buffer_size(); if (!buffer_size) { - LOG_ERROR("Not enough free device memory to start trace capturing."); + LOG_ERROR("Not enough free device memory to start trace capturing"); return ERROR_FAIL; } ret = jaylink_swo_get_speeds(devh, JAYLINK_SWO_MODE_UART, &speed); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_swo_get_speeds() failed: %s.", + LOG_ERROR("jaylink_swo_get_speeds() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } @@ -1382,49 +1381,49 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, max_freq = speed.freq / speed.min_div; if (*trace_freq > max_freq) { - LOG_INFO("Given SWO frequency too high, using %" PRIu32 " Hz instead.", + LOG_INFO("Given SWO frequency too high, using %" PRIu32 " Hz instead", max_freq); *trace_freq = max_freq; } else if (*trace_freq < min_freq) { - LOG_INFO("Given SWO frequency too low, using %" PRIu32 " Hz instead.", + LOG_INFO("Given SWO frequency too low, using %" PRIu32 " Hz instead", min_freq); *trace_freq = min_freq; } else if (*trace_freq != speed.freq / divider) { *trace_freq = speed.freq / divider; LOG_INFO("Given SWO frequency is not supported by the device, " - "using %u Hz instead.", *trace_freq); + "using %u Hz instead", *trace_freq); } if (!calculate_swo_prescaler(traceclkin_freq, *trace_freq, prescaler)) { LOG_ERROR("SWO frequency is not suitable. Please choose a " - "different frequency or use auto-detection."); + "different frequency or use auto-detection"); return ERROR_FAIL; } } else { - LOG_INFO("Trying to auto-detect SWO frequency."); + LOG_INFO("Trying to auto-detect SWO frequency"); if (!detect_swo_freq_and_prescaler(speed, traceclkin_freq, trace_freq, prescaler)) { LOG_ERROR("Maximum permitted frequency deviation of %.02f %% " - "could not be achieved.", SWO_MAX_FREQ_DEV); - LOG_ERROR("Auto-detection of SWO frequency failed."); + "could not be achieved", SWO_MAX_FREQ_DEV); + LOG_ERROR("Auto-detection of SWO frequency failed"); return ERROR_FAIL; } - LOG_INFO("Using SWO frequency of %u Hz.", *trace_freq); + LOG_INFO("Using SWO frequency of %u Hz", *trace_freq); } ret = jaylink_swo_start(devh, JAYLINK_SWO_MODE_UART, *trace_freq, buffer_size); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_start_swo() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_start_swo() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } - LOG_DEBUG("Using %" PRIu32 " bytes device memory for trace capturing.", + LOG_DEBUG("Using %" PRIu32 " bytes device memory for trace capturing", buffer_size); /* @@ -1443,7 +1442,7 @@ COMMAND_HANDLER(jlink_handle_config_usb_address_command) if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { command_print(CMD, "Reading configuration is not supported by the " - "device."); + "device"); return ERROR_OK; } @@ -1451,19 +1450,18 @@ COMMAND_HANDLER(jlink_handle_config_usb_address_command) show_config_usb_address(CMD); } else if (CMD_ARGC == 1) { if (sscanf(CMD_ARGV[0], "%" SCNd8, &tmp) != 1) { - command_print(CMD, "Invalid USB address: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]); return ERROR_FAIL; } if (tmp > JAYLINK_USB_ADDRESS_3) { - command_print(CMD, "Invalid USB address: %u.", tmp); + command_print(CMD, "Invalid USB address: %u", tmp); return ERROR_FAIL; } tmp_config.usb_address = tmp; } else { - command_print(CMD, "Need exactly one argument for jlink config " - "usb."); + command_print(CMD, "Need exactly one argument for jlink config usb"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1476,13 +1474,13 @@ COMMAND_HANDLER(jlink_handle_config_target_power_command) if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { command_print(CMD, "Reading configuration is not supported by the " - "device."); + "device"); return ERROR_OK; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) { command_print(CMD, "Target power supply is not supported by the " - "device."); + "device"); return ERROR_OK; } @@ -1494,14 +1492,14 @@ COMMAND_HANDLER(jlink_handle_config_target_power_command) } else if (!strcmp(CMD_ARGV[0], "off")) { enable = false; } else { - command_print(CMD, "Invalid argument: %s.", CMD_ARGV[0]); + command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]); return ERROR_FAIL; } tmp_config.target_power = enable; } else { command_print(CMD, "Need exactly one argument for jlink config " - "targetpower."); + "targetpower"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1517,13 +1515,13 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command) if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { command_print(CMD, "Reading configuration is not supported by the " - "device."); + "device"); return ERROR_OK; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) { command_print(CMD, "Ethernet connectivity is not supported by the " - "device."); + "device"); return ERROR_OK; } @@ -1534,7 +1532,7 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command) if ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' || str[8] != ':' || str[11] != ':' || str[14] != ':')) { - command_print(CMD, "Invalid MAC address format."); + command_print(CMD, "Invalid MAC address format"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1544,19 +1542,18 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command) } if (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) { - command_print(CMD, "Invalid MAC address: zero address."); + command_print(CMD, "Invalid MAC address: zero address"); return ERROR_COMMAND_SYNTAX_ERROR; } if (!(0x01 & addr[0])) { - command_print(CMD, "Invalid MAC address: multicast address."); + command_print(CMD, "Invalid MAC address: multicast address"); return ERROR_COMMAND_SYNTAX_ERROR; } memcpy(tmp_config.mac_address, addr, sizeof(addr)); } else { - command_print(CMD, "Need exactly one argument for jlink config " - " mac."); + command_print(CMD, "Need exactly one argument for jlink config mac"); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1605,13 +1602,13 @@ COMMAND_HANDLER(jlink_handle_config_ip_address_command) if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { command_print(CMD, "Reading configuration is not supported by the " - "device."); + "device"); return ERROR_OK; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) { command_print(CMD, "Ethernet connectivity is not supported by the " - "device."); + "device"); return ERROR_OK; } @@ -1662,44 +1659,44 @@ COMMAND_HANDLER(jlink_handle_config_write_command) if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { command_print(CMD, "Reading configuration is not supported by the " - "device."); + "device"); return ERROR_OK; } if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_WRITE_CONFIG)) { command_print(CMD, "Writing configuration is not supported by the " - "device."); + "device"); return ERROR_OK; } if (!memcmp(&config, &tmp_config, sizeof(struct device_config))) { command_print(CMD, "Operation not performed due to no changes in " - "the configuration."); + "the configuration"); return ERROR_OK; } ret = jaylink_write_raw_config(devh, (const uint8_t *)&tmp_config); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_write_raw_config() failed: %s.", + LOG_ERROR("jaylink_write_raw_config() failed: %s", jaylink_strerror(ret)); return ERROR_FAIL; } if (!read_device_config(&config)) { - LOG_ERROR("Failed to read device configuration for verification."); + LOG_ERROR("Failed to read device configuration for verification"); return ERROR_FAIL; } if (memcmp(&config, &tmp_config, sizeof(struct device_config))) { LOG_ERROR("Verification of device configuration failed. Please check " - "your device."); + "your device"); return ERROR_FAIL; } memcpy(&tmp_config, &config, sizeof(struct device_config)); command_print(CMD, "The new device configuration applies after power " - "cycling the J-Link device."); + "cycling the J-Link device"); return ERROR_OK; } @@ -1707,7 +1704,7 @@ COMMAND_HANDLER(jlink_handle_config_write_command) COMMAND_HANDLER(jlink_handle_config_command) { if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) { - command_print(CMD, "Device doesn't support reading configuration."); + command_print(CMD, "Device doesn't support reading configuration"); return ERROR_OK; } @@ -1730,7 +1727,7 @@ COMMAND_HANDLER(jlink_handle_emucom_write_command) return ERROR_COMMAND_SYNTAX_ERROR; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) { - LOG_ERROR("Device does not support EMUCOM."); + LOG_ERROR("Device does not support EMUCOM"); return ERROR_FAIL; } @@ -1739,21 +1736,21 @@ COMMAND_HANDLER(jlink_handle_emucom_write_command) tmp = strlen(CMD_ARGV[1]); if (tmp % 2 != 0) { - LOG_ERROR("Data must be encoded as hexadecimal pairs."); + LOG_ERROR("Data must be encoded as hexadecimal pairs"); return ERROR_COMMAND_ARGUMENT_INVALID; } buf = malloc(tmp / 2); if (!buf) { - LOG_ERROR("Failed to allocate buffer."); + LOG_ERROR("Failed to allocate buffer"); return ERROR_FAIL; } dummy = unhexify(buf, CMD_ARGV[1], tmp / 2); if (dummy != (tmp / 2)) { - LOG_ERROR("Data must be encoded as hexadecimal pairs."); + LOG_ERROR("Data must be encoded as hexadecimal pairs"); free(buf); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -1764,15 +1761,15 @@ COMMAND_HANDLER(jlink_handle_emucom_write_command) free(buf); if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) { - LOG_ERROR("Channel not supported by the device."); + LOG_ERROR("Channel not supported by the device"); return ERROR_FAIL; } else if (ret != JAYLINK_OK) { - LOG_ERROR("Failed to write to channel: %s.", jaylink_strerror(ret)); + LOG_ERROR("Failed to write to channel: %s", jaylink_strerror(ret)); return ERROR_FAIL; } if (length != (tmp / 2)) - LOG_WARNING("Only %" PRIu32 " bytes written to the channel.", length); + LOG_WARNING("Only %" PRIu32 " bytes written to the channel", length); return ERROR_OK; } @@ -1789,7 +1786,7 @@ COMMAND_HANDLER(jlink_handle_emucom_read_command) return ERROR_COMMAND_SYNTAX_ERROR; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) { - LOG_ERROR("Device does not support EMUCOM."); + LOG_ERROR("Device does not support EMUCOM"); return ERROR_FAIL; } @@ -1799,23 +1796,23 @@ COMMAND_HANDLER(jlink_handle_emucom_read_command) buf = malloc(length * 3 + 1); if (!buf) { - LOG_ERROR("Failed to allocate buffer."); + LOG_ERROR("Failed to allocate buffer"); return ERROR_FAIL; } ret = jaylink_emucom_read(devh, channel, buf, &length); if (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) { - LOG_ERROR("Channel is not supported by the device."); + LOG_ERROR("Channel is not supported by the device"); free(buf); return ERROR_FAIL; } else if (ret == JAYLINK_ERR_DEV_NOT_AVAILABLE) { LOG_ERROR("Channel is not available for the requested amount of data. " - "%" PRIu32 " bytes are available.", length); + "%" PRIu32 " bytes are available", length); free(buf); return ERROR_FAIL; } else if (ret != JAYLINK_OK) { - LOG_ERROR("Failed to read from channel: %s.", jaylink_strerror(ret)); + LOG_ERROR("Failed to read from channel: %s", jaylink_strerror(ret)); free(buf); return ERROR_FAIL; } @@ -1823,7 +1820,7 @@ COMMAND_HANDLER(jlink_handle_emucom_read_command) tmp = hexify((char *)buf + length, buf, length, 2 * length + 1); if (tmp != 2 * length) { - LOG_ERROR("Failed to convert data into hexadecimal string."); + LOG_ERROR("Failed to convert data into hexadecimal string"); free(buf); return ERROR_FAIL; } @@ -2081,7 +2078,7 @@ static int jlink_flush(void) tap_length, jtag_command_version); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_jtag_io() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_jtag_io() failed: %s", jaylink_strerror(ret)); jlink_tap_init(); return ERROR_JTAG_QUEUE_FAILED; } @@ -2092,7 +2089,7 @@ static int jlink_flush(void) buf_set_buf(tdo_buffer, p->first, p->buffer, p->buffer_offset, p->length); - LOG_DEBUG_IO("Pending scan result, length = %d.", p->length); + LOG_DEBUG_IO("Pending scan result, length = %d", p->length); } jlink_tap_init(); @@ -2157,7 +2154,7 @@ static int jlink_swd_switch_seq(enum swd_special_seq seq) s_len = swd_seq_swd_to_jtag_len; break; default: - LOG_ERROR("Sequence %d not supported.", seq); + LOG_ERROR("Sequence %d not supported", seq); return ERROR_FAIL; } @@ -2171,10 +2168,10 @@ static int jlink_swd_run_queue(void) int i; int ret; - LOG_DEBUG("Executing %d queued transactions.", pending_scan_results_length); + LOG_DEBUG("Executing %d queued transactions", pending_scan_results_length); if (queued_retval != ERROR_OK) { - LOG_DEBUG("Skipping due to previous errors: %d.", queued_retval); + LOG_DEBUG("Skipping due to previous errors: %d", queued_retval); goto skip; } @@ -2187,7 +2184,7 @@ static int jlink_swd_run_queue(void) ret = jaylink_swd_io(devh, tms_buffer, tdi_buffer, tdo_buffer, tap_length); if (ret != JAYLINK_OK) { - LOG_ERROR("jaylink_swd_io() failed: %s.", jaylink_strerror(ret)); + LOG_ERROR("jaylink_swd_io() failed: %s", jaylink_strerror(ret)); goto skip; } @@ -2204,7 +2201,7 @@ static int jlink_swd_run_queue(void) int parity = buf_get_u32(tdo_buffer, 3 + 32 + pending_scan_results_buffer[i].first, 1); if (parity != parity_u32(data)) { - LOG_ERROR("SWD: Read data parity mismatch."); + LOG_ERROR("SWD: Read data parity mismatch"); queued_retval = ERROR_FAIL; goto skip; } diff --git a/src/jtag/drivers/jtag_dpi.c b/src/jtag/drivers/jtag_dpi.c index 7cac200..f5a67dd 100644 --- a/src/jtag/drivers/jtag_dpi.c +++ b/src/jtag/drivers/jtag_dpi.c @@ -301,7 +301,7 @@ static int jtag_dpi_init(void) serv_addr.sin_addr.s_addr = inet_addr(server_address); if (serv_addr.sin_addr.s_addr == INADDR_NONE) { - LOG_ERROR("inet_addr error occured"); + LOG_ERROR("inet_addr error occurred"); return ERROR_FAIL; } diff --git a/src/jtag/drivers/nulink_usb.c b/src/jtag/drivers/nulink_usb.c index 48a5c79..3eea9de 100644 --- a/src/jtag/drivers/nulink_usb.c +++ b/src/jtag/drivers/nulink_usb.c @@ -844,11 +844,11 @@ static int nulink_usb_read_mem(void *handle, uint32_t addr, uint32_t size, /* the nulink only supports 8/32bit memory read/writes * honour 32bit, all others will be handled as 8bit access */ if (size == 4) { - /* When in jtag mode the nulink uses the auto-increment functinality. + /* When in jtag mode the nulink uses the auto-increment functionality. * However it expects us to pass the data correctly, this includes * alignment and any page boundaries. We already do this as part of the * adi_v5 implementation, but the nulink is a hla adapter and so this - * needs implementiong manually. + * needs implementing manually. * currently this only affects jtag mode, they do single * access in SWD mode - but this may change and so we do it for both modes */ @@ -909,11 +909,11 @@ static int nulink_usb_write_mem(void *handle, uint32_t addr, uint32_t size, /* the nulink only supports 8/32bit memory read/writes * honour 32bit, all others will be handled as 8bit access */ if (size == 4) { - /* When in jtag mode the nulink uses the auto-increment functinality. + /* When in jtag mode the nulink uses the auto-increment functionality. * However it expects us to pass the data correctly, this includes * alignment and any page boundaries. We already do this as part of the * adi_v5 implementation, but the nulink is a hla adapter and so this - * needs implementiong manually. + * needs implementing manually. * currently this only affects jtag mode, do single * access in SWD mode - but this may change and so we do it for both modes */ diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 60a2c31..c68bbb3 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -413,17 +413,17 @@ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, i * Map the relevant features, quirks and workaround for specific firmware * version of stlink */ -#define STLINK_F_HAS_TRACE BIT(0) -#define STLINK_F_HAS_SWD_SET_FREQ BIT(1) -#define STLINK_F_HAS_JTAG_SET_FREQ BIT(2) -#define STLINK_F_HAS_MEM_16BIT BIT(3) -#define STLINK_F_HAS_GETLASTRWSTATUS2 BIT(4) -#define STLINK_F_HAS_DAP_REG BIT(5) -#define STLINK_F_QUIRK_JTAG_DP_READ BIT(6) -#define STLINK_F_HAS_AP_INIT BIT(7) -#define STLINK_F_HAS_DPBANKSEL BIT(8) -#define STLINK_F_HAS_RW8_512BYTES BIT(9) -#define STLINK_F_FIX_CLOSE_AP BIT(10) +#define STLINK_F_HAS_TRACE BIT(0) /* v2>=j13 || v3 */ +#define STLINK_F_HAS_GETLASTRWSTATUS2 BIT(1) /* v2>=j15 || v3 */ +#define STLINK_F_HAS_SWD_SET_FREQ BIT(2) /* v2>=j22 */ +#define STLINK_F_HAS_JTAG_SET_FREQ BIT(3) /* v2>=j24 */ +#define STLINK_F_QUIRK_JTAG_DP_READ BIT(4) /* v2>=j24 && v2<j32 */ +#define STLINK_F_HAS_DAP_REG BIT(5) /* v2>=j24 || v3 */ +#define STLINK_F_HAS_MEM_16BIT BIT(6) /* v2>=j26 || v3 */ +#define STLINK_F_HAS_AP_INIT BIT(7) /* v2>=j28 || v3 */ +#define STLINK_F_FIX_CLOSE_AP BIT(8) /* v2>=j29 || v3 */ +#define STLINK_F_HAS_DPBANKSEL BIT(9) /* v2>=j32 || v3>=j2 */ +#define STLINK_F_HAS_RW8_512BYTES BIT(10) /* v3>=j6 */ /* aliases */ #define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE @@ -3904,7 +3904,7 @@ static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, if (retval != ERROR_OK) return retval; - data = data ? : &dummy; + data = data ? data : &dummy; if (stlink_dap_handle->version.flags & STLINK_F_QUIRK_JTAG_DP_READ && stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) { /* Quirk required in JTAG. Read RDBUFF to get the data */ @@ -3969,7 +3969,7 @@ static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned reg, if (retval != ERROR_OK) return retval; } - data = data ? : &dummy; + data = data ? data : &dummy; retval = stlink_read_dap_register(stlink_dap_handle, ap->ap_num, reg, data); dap->stlink_flush_ap_write = false; diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index c312468..aa7c240 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -561,8 +561,8 @@ static int ublast_read_byteshifted_tdos(uint8_t *buf, int nb_bytes) * - first bit is stored in byte0, bit0 (LSB) * - second bit is stored in byte0, bit 1 * ... - * - eight bit is sotred in byte0, bit 7 - * - ninth bit is sotred in byte1, bit 0 + * - eight bit is stored in byte0, bit 7 + * - ninth bit is stored in byte1, bit 0 * - etc ... * * Returns ERROR_OK if OK, ERROR_xxx if a read error occurred diff --git a/src/jtag/drivers/versaloon/versaloon.c b/src/jtag/drivers/versaloon/versaloon.c index 6fea888..e564d8b 100644 --- a/src/jtag/drivers/versaloon/versaloon.c +++ b/src/jtag/drivers/versaloon/versaloon.c @@ -124,7 +124,7 @@ void versaloon_free_want_pos(void) } versaloon_want_pos = NULL; - for (i = 0; i < dimof(versaloon_pending); i++) { + for (i = 0; i < ARRAY_SIZE(versaloon_pending); i++) { tmp = versaloon_pending[i].pos; while (tmp != NULL) { free_tmp = tmp; diff --git a/src/jtag/drivers/versaloon/versaloon_include.h b/src/jtag/drivers/versaloon/versaloon_include.h index 4ca81d5..a954b48 100644 --- a/src/jtag/drivers/versaloon/versaloon_include.h +++ b/src/jtag/drivers/versaloon/versaloon_include.h @@ -27,7 +27,6 @@ #define PARAM_CHECK 1 #define sleep_ms(ms) jtag_sleep((ms) * 1000) -#define dimof(arr) (sizeof(arr) / sizeof((arr)[0])) #define TO_STR(name) #name #define RESULT int diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index c492807..85a1b81 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -356,7 +356,7 @@ static bool usb_connect(void) /* Check for device vid/pid match */ libusb_get_device_descriptor(list[i], &desc); match = false; - for (device = 0; device < sizeof(vids)/sizeof(vids[0]); device++) { + for (device = 0; device < ARRAY_SIZE(vids); device++) { if (desc.idVendor == vids[device] && desc.idProduct == pids[device]) { match = true; diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 04e01d2..1565176 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -359,7 +359,7 @@ static const struct command_registration hl_interface_command_handlers[] = { .handler = &hl_interface_handle_vid_pid_command, .mode = COMMAND_CONFIG, .help = "the vendor and product ID of the adapter", - .usage = "(vid pid)* ", + .usage = "(vid pid)*", }, { .name = "hla_stlink_backend", diff --git a/src/jtag/hla/hla_tcl.c b/src/jtag/hla/hla_tcl.c index 73f78fc..2998498 100644 --- a/src/jtag/hla/hla_tcl.c +++ b/src/jtag/hla/hla_tcl.c @@ -28,11 +28,11 @@ #include <transport/transport.h> #include <helper/time_support.h> -static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, +static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi, struct jtag_tap *pTap) { jim_wide w; - int e = Jim_GetOpt_Wide(goi, &w); + int e = jim_getopt_wide(goi, &w); if (e != JIM_OK) { Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name); @@ -60,14 +60,14 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, #define NTAP_OPT_EXPECTED_ID 5 #define NTAP_OPT_VERSION 6 -static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi) +static int jim_hl_newtap_cmd(struct jim_getopt_info *goi) { struct jtag_tap *pTap; int x; int e; - Jim_Nvp *n; + struct jim_nvp *n; char *cp; - const Jim_Nvp opts[] = { + const struct jim_nvp opts[] = { { .name = "-irlen", .value = NTAP_OPT_IRLEN }, { .name = "-irmask", .value = NTAP_OPT_IRMASK }, { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE }, @@ -95,10 +95,10 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi) } const char *tmp; - Jim_GetOpt_String(goi, &tmp, NULL); + jim_getopt_string(goi, &tmp, NULL); pTap->chip = strdup(tmp); - Jim_GetOpt_String(goi, &tmp, NULL); + jim_getopt_string(goi, &tmp, NULL); pTap->tapname = strdup(tmp); /* name + dot + name + null */ @@ -111,9 +111,9 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi) pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc); while (goi->argc) { - e = Jim_GetOpt_Nvp(goi, opts, &n); + e = jim_getopt_nvp(goi, opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, opts, 0); + jim_getopt_nvp_unknown(goi, opts, 0); free(cp); free(pTap); return e; @@ -132,7 +132,7 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi) case NTAP_OPT_IRMASK: case NTAP_OPT_IRCAPTURE: /* dummy read to ignore the next argument */ - Jim_GetOpt_Wide(goi, NULL); + jim_getopt_wide(goi, NULL); break; } /* switch (n->value) */ } /* while (goi->argc) */ @@ -146,7 +146,7 @@ static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi) int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); return jim_hl_newtap_cmd(&goi); } diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c index 1002826..d925b17 100644 --- a/src/jtag/hla/hla_transport.c +++ b/src/jtag/hla/hla_transport.c @@ -76,7 +76,7 @@ hl_transport_jtag_subcommand_handlers[] = { .help = "Create a new TAP instance named basename.tap_type, " "and appends it to the scan chain.", .usage = "basename tap_type '-irlen' count " - "['-expected_id' number] ", + "['-expected_id' number]", }, { .name = "init", diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h index c6fdfaf..0624c55 100644 --- a/src/jtag/minidriver.h +++ b/src/jtag/minidriver.h @@ -32,7 +32,7 @@ * interface functions, instead of the built-in asynchronous driver * module that is used by the standard JTAG interface drivers. * - * In addtion to the functions defined in the @c minidriver.h file, the + * In addition to the functions defined in the @c minidriver.h file, the * @c jtag_minidriver.h file must declare the following functions (or * define static inline versions of them): * - jtag_add_callback diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index f1e69e5..3060c5c 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -81,9 +81,10 @@ proc srst_asserted {} { # measure actual JTAG clock proc measure_clk {} { set start_time [ms]; - set iterations 10000000; + set iterations 10000000; runtest $iterations; - echo "Running at more than [expr $iterations.0 / ([ms]-$start_time)] kHz"; + set speed [expr "$iterations.0 / ([ms] - $start_time)"] + echo "Running at more than $speed kHz"; } add_help_text measure_clk "Runs a test to measure the JTAG clk. Useful with RCLK / RTCK." @@ -119,6 +120,7 @@ proc jtag_ntrst_assert_width args { # # FIXME phase these aids out after some releases # +lappend _telnet_autocomplete_skip jtag_reset proc jtag_reset args { echo "DEPRECATED! use 'adapter \[de\]assert' not 'jtag_reset'" switch $args { @@ -135,51 +137,61 @@ proc jtag_reset args { } } +lappend _telnet_autocomplete_skip adapter_khz proc adapter_khz args { echo "DEPRECATED! use 'adapter speed' not 'adapter_khz'" eval adapter speed $args } +lappend _telnet_autocomplete_skip adapter_name proc adapter_name args { echo "DEPRECATED! use 'adapter name' not 'adapter_name'" eval adapter name $args } +lappend _telnet_autocomplete_skip adapter_nsrst_delay proc adapter_nsrst_delay args { echo "DEPRECATED! use 'adapter srst delay' not 'adapter_nsrst_delay'" eval adapter srst delay $args } +lappend _telnet_autocomplete_skip adapter_nsrst_assert_width proc adapter_nsrst_assert_width args { echo "DEPRECATED! use 'adapter srst pulse_width' not 'adapter_nsrst_assert_width'" eval adapter srst pulse_width $args } +lappend _telnet_autocomplete_skip interface proc interface args { echo "DEPRECATED! use 'adapter driver' not 'interface'" eval adapter driver $args } +lappend _telnet_autocomplete_skip interface_transports proc interface_transports args { echo "DEPRECATED! use 'adapter transports' not 'interface_transports'" eval adapter transports $args } +lappend _telnet_autocomplete_skip interface_list proc interface_list args { echo "DEPRECATED! use 'adapter list' not 'interface_list'" eval adapter list $args } +lappend _telnet_autocomplete_skip ftdi_location proc ftdi_location args { echo "DEPRECATED! use 'adapter usb location' not 'ftdi_location'" eval adapter usb location $args } +lappend _telnet_autocomplete_skip xds110_serial proc xds110_serial args { echo "DEPRECATED! use 'xds110 serial' not 'xds110_serial'" eval xds110 serial $args } +lappend _telnet_autocomplete_skip xds110_supply_voltage proc xds110_supply_voltage args { echo "DEPRECATED! use 'xds110 supply' not 'xds110_supply_voltage'" eval xds110 supply $args @@ -189,6 +201,7 @@ proc hla {cmd args} { tailcall "hla $cmd" {*}$args } +lappend _telnet_autocomplete_skip "hla newtap" proc "hla newtap" {args} { echo "DEPRECATED! use 'swj_newdap' not 'hla newtap'" eval swj_newdap $args diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 8a52c0f..970bd37 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -49,7 +49,7 @@ * Holds support for accessing JTAG-specific mechanisms from TCl scripts. */ -static const Jim_Nvp nvp_jtag_tap_event[] = { +static const struct jim_nvp nvp_jtag_tap_event[] = { { .value = JTAG_TRST_ASSERTED, .name = "post-reset" }, { .value = JTAG_TAP_EVENT_SETUP, .name = "setup" }, { .value = JTAG_TAP_EVENT_ENABLE, .name = "tap-enable" }, @@ -310,24 +310,24 @@ enum jtag_tap_cfg_param { JCFG_IDCODE, }; -static Jim_Nvp nvp_config_opts[] = { +static struct jim_nvp nvp_config_opts[] = { { .name = "-event", .value = JCFG_EVENT }, { .name = "-idcode", .value = JCFG_IDCODE }, { .name = NULL, .value = -1 } }; -static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap *tap) +static int jtag_tap_configure_event(struct jim_getopt_info *goi, struct jtag_tap *tap) { if (goi->argc == 0) { Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event <event-name> ..."); return JIM_ERR; } - Jim_Nvp *n; - int e = Jim_GetOpt_Nvp(goi, nvp_jtag_tap_event, &n); + struct jim_nvp *n; + int e = jim_getopt_nvp(goi, nvp_jtag_tap_event, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_jtag_tap_event, 1); + jim_getopt_nvp_unknown(goi, nvp_jtag_tap_event, 1); return e; } @@ -369,7 +369,7 @@ static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap *tap) jteap->event = n->value; Jim_Obj *o; - Jim_GetOpt_Obj(goi, &o); + jim_getopt_obj(goi, &o); jteap->body = Jim_DuplicateObj(goi->interp, o); Jim_IncrRefCount(jteap->body); @@ -386,16 +386,16 @@ static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap *tap) return JIM_OK; } -static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap *tap) +static int jtag_tap_configure_cmd(struct jim_getopt_info *goi, struct jtag_tap *tap) { /* parse config or cget options */ while (goi->argc > 0) { Jim_SetEmptyResult(goi->interp); - Jim_Nvp *n; - int e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n); + struct jim_nvp *n; + int e = jim_getopt_nvp(goi, nvp_config_opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0); + jim_getopt_nvp_unknown(goi, nvp_config_opts, 0); return e; } @@ -439,11 +439,11 @@ static int is_bad_irval(int ir_length, jim_wide w) return (w & v) != 0; } -static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, +static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi, struct jtag_tap *pTap) { jim_wide w; - int e = Jim_GetOpt_Wide(goi, &w); + int e = jim_getopt_wide(goi, &w); if (e != JIM_OK) { Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name); return e; @@ -470,11 +470,11 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, #define NTAP_OPT_EXPECTED_ID 5 #define NTAP_OPT_VERSION 6 -static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi, +static int jim_newtap_ir_param(struct jim_nvp *n, struct jim_getopt_info *goi, struct jtag_tap *pTap) { jim_wide w; - int e = Jim_GetOpt_Wide(goi, &w); + int e = jim_getopt_wide(goi, &w); if (e != JIM_OK) { Jim_SetResultFormatted(goi->interp, "option: %s bad parameter", n->name); @@ -516,14 +516,14 @@ static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi, return JIM_OK; } -static int jim_newtap_cmd(Jim_GetOptInfo *goi) +static int jim_newtap_cmd(struct jim_getopt_info *goi) { struct jtag_tap *pTap; int x; int e; - Jim_Nvp *n; + struct jim_nvp *n; char *cp; - const Jim_Nvp opts[] = { + const struct jim_nvp opts[] = { { .name = "-irlen", .value = NTAP_OPT_IRLEN }, { .name = "-irmask", .value = NTAP_OPT_IRMASK }, { .name = "-ircapture", .value = NTAP_OPT_IRCAPTURE }, @@ -550,10 +550,10 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi) } const char *tmp; - Jim_GetOpt_String(goi, &tmp, NULL); + jim_getopt_string(goi, &tmp, NULL); pTap->chip = strdup(tmp); - Jim_GetOpt_String(goi, &tmp, NULL); + jim_getopt_string(goi, &tmp, NULL); pTap->tapname = strdup(tmp); /* name + dot + name + null */ @@ -580,9 +580,9 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi) pTap->ir_capture_value = 0x01; while (goi->argc) { - e = Jim_GetOpt_Nvp(goi, opts, &n); + e = jim_getopt_nvp(goi, opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, opts, 0); + jim_getopt_nvp_unknown(goi, opts, 0); free(cp); free(pTap); return e; @@ -644,7 +644,7 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e) if (jteap->event != e) continue; - Jim_Nvp *nvp = Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e); + struct jim_nvp *nvp = jim_nvp_value2name_simple(nvp_jtag_tap_event, e); LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s", tap->dotted_name, e, nvp->name, Jim_GetString(jteap->body, NULL)); @@ -678,8 +678,8 @@ 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) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); + 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; @@ -697,8 +697,8 @@ static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { int e = ERROR_OK; - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); + 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; @@ -719,8 +719,8 @@ static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const int jim_jtag_newtap(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc-1, argv + 1); return jim_newtap_cmd(&goi); } @@ -759,8 +759,8 @@ int jim_jtag_tap_enabler(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { struct command *c = jim_to_command(interp); const char *cmd_name = c->name; - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc-1, argv + 1); if (goi.argc != 1) { Jim_SetResultFormatted(goi.interp, "usage: %s <name>", cmd_name); return JIM_ERR; @@ -797,8 +797,8 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { struct command *c = jim_to_command(interp); const char *cmd_name = c->name; - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc-1, argv + 1); goi.isconfigure = !strcmp(cmd_name, "configure"); if (goi.argc < 2 + goi.isconfigure) { Jim_WrongNumArgs(goi.interp, 0, NULL, @@ -809,7 +809,7 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) struct jtag_tap *t; Jim_Obj *o; - Jim_GetOpt_Obj(&goi, &o); + jim_getopt_obj(&goi, &o); t = jtag_tap_by_jim_obj(goi.interp, o); if (t == NULL) return JIM_ERR; @@ -819,8 +819,8 @@ int jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_jtag_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1); + 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; @@ -887,7 +887,7 @@ static const struct command_registration jtag_subcommand_handlers[] = { "['-expected_id' number] " "['-ignore-version'] " "['-ircapture' number] " - "['-mask' number] ", + "['-mask' number]", }, { .name = "tapisenabled", @@ -1353,7 +1353,7 @@ static const struct command_registration jtag_command_handlers[] = { .mode = COMMAND_ANY, .help = "Wait for an SRST deassert. " "Useful for cases where you need something to happen within ms " - "of an srst deassert. Timeout in ms ", + "of an srst deassert. Timeout in ms", .usage = "ms", }, { diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index 3a1f114..68b3f2c 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -205,8 +205,6 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = { }, }; -#define FREERTOS_NUM_PARAMS ((int)(sizeof(FreeRTOS_params_list)/sizeof(struct FreeRTOS_params))) - static bool FreeRTOS_detect_rtos(struct target *target); static int FreeRTOS_create(struct target *target); static int FreeRTOS_update_threads(struct rtos *rtos); @@ -878,12 +876,12 @@ static bool FreeRTOS_detect_rtos(struct target *target) static int FreeRTOS_create(struct target *target) { - int i = 0; - while ((i < FREERTOS_NUM_PARAMS) && - (0 != strcmp(FreeRTOS_params_list[i].target_name, target->type->name))) { + unsigned int i = 0; + while (i < ARRAY_SIZE(FreeRTOS_params_list) && + strcmp(FreeRTOS_params_list[i].target_name, target->type->name) != 0) { i++; } - if (i >= FREERTOS_NUM_PARAMS) { + if (i >= ARRAY_SIZE(FreeRTOS_params_list)) { LOG_ERROR("Could not find target in FreeRTOS compatibility list"); return ERROR_FAIL; } @@ -905,5 +903,5 @@ static int FreeRTOS_create(struct target *target) return ERROR_FAIL; } - return 0; + return ERROR_OK; } diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am index de54596..49cb830 100644 --- a/src/rtos/Makefile.am +++ b/src/rtos/Makefile.am @@ -19,6 +19,7 @@ noinst_LTLIBRARIES += %D%/librtos.la %D%/uCOS-III.c \ %D%/nuttx.c \ %D%/hwthread.c \ + %D%/zephyr.c \ %D%/riot.c \ %D%/rtos.h \ %D%/rtos_standard_stackings.h \ diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c index 4041332..99f3bf9 100644 --- a/src/rtos/ThreadX.c +++ b/src/rtos/ThreadX.c @@ -65,7 +65,7 @@ static const struct ThreadX_thread_state ThreadX_thread_states[] = { { 13, "Waiting - Mutex" }, }; -#define THREADX_NUM_STATES (sizeof(ThreadX_thread_states)/sizeof(struct ThreadX_thread_state)) +#define THREADX_NUM_STATES ARRAY_SIZE(ThreadX_thread_states) #define ARM926EJS_REGISTERS_SIZE_SOLICITED (11 * 4) static const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_solicited[] = { @@ -177,8 +177,6 @@ static const struct ThreadX_params ThreadX_params_list[] = { }, }; -#define THREADX_NUM_PARAMS ((int)(sizeof(ThreadX_params_list)/sizeof(struct ThreadX_params))) - enum ThreadX_symbol_values { ThreadX_VAL_tx_thread_current_ptr = 0, ThreadX_VAL_tx_thread_created_ptr = 1, @@ -597,18 +595,14 @@ static int ThreadX_get_thread_detail(struct rtos *rtos, static int ThreadX_create(struct target *target) { - int i = 0; - while ((i < THREADX_NUM_PARAMS) && - (0 != strcmp(ThreadX_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= THREADX_NUM_PARAMS) { - LOG_ERROR("Could not find target in ThreadX compatibility list"); - return -1; - } + for (unsigned int i = 0; i < ARRAY_SIZE(ThreadX_params_list); i++) + if (strcmp(ThreadX_params_list[i].target_name, target->type->name) == 0) { + target->rtos->rtos_specific_params = (void *)&ThreadX_params_list[i]; + target->rtos->current_thread = 0; + target->rtos->thread_details = NULL; + return 0; + } - target->rtos->rtos_specific_params = (void *) &ThreadX_params_list[i]; - target->rtos->current_thread = 0; - target->rtos->thread_details = NULL; - return 0; + LOG_ERROR("Could not find target in ThreadX compatibility list"); + return -1; } diff --git a/src/rtos/chibios.c b/src/rtos/chibios.c index 29abede..2a23017 100644 --- a/src/rtos/chibios.c +++ b/src/rtos/chibios.c @@ -74,7 +74,7 @@ static const char * const chibios_thread_states[] = { "READY", "CURRENT", "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "FINAL" }; -#define CHIBIOS_NUM_STATES (sizeof(chibios_thread_states)/sizeof(char *)) +#define CHIBIOS_NUM_STATES ARRAY_SIZE(chibios_thread_states) /* Maximum ChibiOS thread name. There is no real limit set by ChibiOS but 64 * chars ought to be enough. @@ -100,7 +100,6 @@ static struct chibios_params chibios_params_list[] = { NULL, /* stacking_info */ } }; -#define CHIBIOS_NUM_PARAMS ((int)(sizeof(chibios_params_list)/sizeof(struct chibios_params))) static bool chibios_detect_rtos(struct target *target); static int chibios_create(struct target *target); @@ -529,17 +528,13 @@ static bool chibios_detect_rtos(struct target *target) static int chibios_create(struct target *target) { - int i = 0; - while ((i < CHIBIOS_NUM_PARAMS) && - (0 != strcmp(chibios_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= CHIBIOS_NUM_PARAMS) { - LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility " - "list", target->type->name); - return -1; - } + for (unsigned int i = 0; i < ARRAY_SIZE(chibios_params_list); i++) + if (strcmp(chibios_params_list[i].target_name, target->type->name) == 0) { + target->rtos->rtos_specific_params = (void *)&chibios_params_list[i]; + return 0; + } - target->rtos->rtos_specific_params = (void *) &chibios_params_list[i]; - return 0; + LOG_WARNING("Could not find target \"%s\" in ChibiOS compatibility " + "list", target->type->name); + return -1; } diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c index 9501a55..1b1e73e 100644 --- a/src/rtos/eCos.c +++ b/src/rtos/eCos.c @@ -47,7 +47,7 @@ static const struct eCos_thread_state eCos_thread_states[] = { { 16, "Exited" } }; -#define ECOS_NUM_STATES (sizeof(eCos_thread_states)/sizeof(struct eCos_thread_state)) +#define ECOS_NUM_STATES ARRAY_SIZE(eCos_thread_states) struct eCos_params { const char *target_name; @@ -73,8 +73,6 @@ static const struct eCos_params eCos_params_list[] = { } }; -#define ECOS_NUM_PARAMS ((int)(sizeof(eCos_params_list)/sizeof(struct eCos_params))) - enum eCos_symbol_values { eCos_VAL_thread_list = 0, eCos_VAL_current_thread_ptr = 1 @@ -375,18 +373,14 @@ static bool eCos_detect_rtos(struct target *target) static int eCos_create(struct target *target) { - int i = 0; - while ((i < ECOS_NUM_PARAMS) && - (0 != strcmp(eCos_params_list[i].target_name, target->type->name))) { - i++; - } - if (i >= ECOS_NUM_PARAMS) { - LOG_ERROR("Could not find target in eCos compatibility list"); - return -1; - } + for (unsigned int i = 0; i < ARRAY_SIZE(eCos_params_list); i++) + if (strcmp(eCos_params_list[i].target_name, target->type->name) == 0) { + target->rtos->rtos_specific_params = (void *)&eCos_params_list[i]; + target->rtos->current_thread = 0; + target->rtos->thread_details = NULL; + return 0; + } - target->rtos->rtos_specific_params = (void *) &eCos_params_list[i]; - target->rtos->current_thread = 0; - target->rtos->thread_details = NULL; - return 0; + LOG_ERROR("Could not find target in eCos compatibility list"); + return -1; } diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c index 0914e31..9f895de 100644 --- a/src/rtos/mqx.c +++ b/src/rtos/mqx.c @@ -222,7 +222,7 @@ static int mqx_is_scheduler_running( return ERROR_FAIL; } /* check first member, the '_mqx_kernel_data->ADDRESSING_CAPABILITY'. - it supose to be set to value 8 */ + it suppose to be set to value 8 */ if (capability_value != 8) { LOG_WARNING("MQX RTOS - value of '_mqx_kernel_data->ADDRESSING_CAPABILITY' contains invalid value"); return ERROR_FAIL; @@ -267,8 +267,7 @@ static int mqx_create( ) { /* check target name against supported architectures */ - int mqx_params_list_num = (sizeof(mqx_params_list)/sizeof(struct mqx_params)); - for (int i = 0; i < mqx_params_list_num; i++) { + for (unsigned int i = 0; i < ARRAY_SIZE(mqx_params_list); i++) { if (0 == strcmp(mqx_params_list[i].target_name, target->type->name)) { target->rtos->rtos_specific_params = (void *)&mqx_params_list[i]; /* LOG_DEBUG("MQX RTOS - valid architecture: %s", target->type->name); */ @@ -351,7 +350,7 @@ static int mqx_update_threads( uint8_t task_name[MQX_THREAD_NAME_LENGTH + 1]; uint32_t task_addr = 0, task_template = 0, task_state = 0; uint32_t task_name_addr = 0, task_id = 0, task_errno = 0; - uint32_t state_index = 0, state_max = 0; + uint32_t state_index = 0; uint32_t extra_info_length = 0; char *state_name = "Unknown"; @@ -412,8 +411,7 @@ static int mqx_update_threads( } task_state &= MQX_TASK_STATE_MASK; /* and search for defined state */ - state_max = (sizeof(mqx_states)/sizeof(struct mqx_state)); - for (state_index = 0; (state_index < state_max); state_index++) { + for (state_index = 0; state_index < ARRAY_SIZE(mqx_states); state_index++) { if (mqx_states[state_index].state == task_state) { state_name = mqx_states[state_index].name; break; diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c index 048f4af..b2151bb 100644 --- a/src/rtos/nuttx.c +++ b/src/rtos/nuttx.c @@ -312,7 +312,7 @@ static int nuttx_update_threads(struct rtos *rtos) state = tcb.dat[state_offset - 8]; thread->extra_info_str = NULL; - if (state < sizeof(task_state_str)/sizeof(char *)) { + if (state < ARRAY_SIZE(task_state_str)) { thread->extra_info_str = malloc(256); snprintf(thread->extra_info_str, 256, "pid:%d, %s", tcb.dat[pid_offset - 8] | diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 8e1b7e9..31e910d 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -39,6 +39,7 @@ extern struct rtos_type uCOS_III_rtos; extern struct rtos_type nuttx_rtos; extern struct rtos_type hwthread_rtos; extern struct rtos_type riot_rtos; +extern struct rtos_type zephyr_rtos; static struct rtos_type *rtos_types[] = { &ThreadX_rtos, @@ -52,6 +53,7 @@ static struct rtos_type *rtos_types[] = { &uCOS_III_rtos, &nuttx_rtos, &riot_rtos, + &zephyr_rtos, /* keep this as last, as it always matches with rtos auto */ &hwthread_rtos, NULL @@ -126,7 +128,7 @@ static int os_alloc_create(struct target *target, struct rtos_type *ostype, return ret; } -int rtos_create(Jim_GetOptInfo *goi, struct target *target) +int rtos_create(struct jim_getopt_info *goi, struct target *target) { int x; const char *cp; @@ -142,7 +144,7 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target) os_free(target); - e = Jim_GetOpt_String(goi, &cp, NULL); + e = jim_getopt_string(goi, &cp, NULL); if (e != JIM_OK) return e; diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h index 7609a9f..bf0cdc5 100644 --- a/src/rtos/rtos.h +++ b/src/rtos/rtos.h @@ -132,7 +132,7 @@ struct rtos_register_stacking { #define GDB_THREAD_PACKET_NOT_CONSUMED (-40) -int rtos_create(Jim_GetOptInfo *goi, struct target *target); +int rtos_create(struct jim_getopt_info *goi, struct target *target); void rtos_destroy(struct target *target); int rtos_set_reg(struct connection *connection, int reg_num, uint8_t *reg_value); diff --git a/src/rtos/zephyr.c b/src/rtos/zephyr.c new file mode 100644 index 0000000..3ef9bcd --- /dev/null +++ b/src/rtos/zephyr.c @@ -0,0 +1,788 @@ +/*************************************************************************** + * Copyright (C) 2017 by Intel Corporation + * Leandro Pereira <leandro.pereira@intel.com> + * Daniel Glöckner <dg@emlix.com>* + * Copyright (C) 2021 by Synopsys, Inc. + * Evgeniy Didin <didin@synopsys.com> + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <helper/time_support.h> +#include <jtag/jtag.h> + +#include "helper/log.h" +#include "helper/types.h" +#include "rtos.h" +#include "rtos_standard_stackings.h" +#include "target/target.h" +#include "target/target_type.h" +#include "target/armv7m.h" +#include "target/arc.h" + +#define UNIMPLEMENTED 0xFFFFFFFFU + +/* ARC specific defines */ +#define ARC_AUX_SEC_BUILD_REG 0xdb +#define ARC_REG_NUM 38 + +/* ARM specific defines */ +#define ARM_XPSR_OFFSET 28 + +struct zephyr_thread { + uint32_t ptr, next_ptr; + uint32_t entry; + uint32_t stack_pointer; + uint8_t state; + uint8_t user_options; + int8_t prio; + char name[64]; +}; + +enum zephyr_offsets { + OFFSET_VERSION, + OFFSET_K_CURR_THREAD, + OFFSET_K_THREADS, + OFFSET_T_ENTRY, + OFFSET_T_NEXT_THREAD, + OFFSET_T_STATE, + OFFSET_T_USER_OPTIONS, + OFFSET_T_PRIO, + OFFSET_T_STACK_POINTER, + OFFSET_T_NAME, + OFFSET_T_ARCH, + OFFSET_T_PREEMPT_FLOAT, + OFFSET_T_COOP_FLOAT, + OFFSET_MAX +}; + +struct zephyr_params { + const char *target_name; + uint8_t size_width; + uint8_t pointer_width; + uint32_t num_offsets; + uint32_t offsets[OFFSET_MAX]; + const struct rtos_register_stacking *callee_saved_stacking; + const struct rtos_register_stacking *cpu_saved_nofp_stacking; + const struct rtos_register_stacking *cpu_saved_fp_stacking; + int (*get_cpu_state)(struct rtos *rtos, target_addr_t *addr, + struct zephyr_params *params, + struct rtos_reg *callee_saved_reg_list, + struct rtos_reg **reg_list, int *num_regs); +}; + +static const struct stack_register_offset arm_callee_saved[] = { + { ARMV7M_R13, 32, 32 }, + { ARMV7M_R4, 0, 32 }, + { ARMV7M_R5, 4, 32 }, + { ARMV7M_R6, 8, 32 }, + { ARMV7M_R7, 12, 32 }, + { ARMV7M_R8, 16, 32 }, + { ARMV7M_R9, 20, 32 }, + { ARMV7M_R10, 24, 32 }, + { ARMV7M_R11, 28, 32 }, +}; + +static const struct stack_register_offset arc_callee_saved[] = { + { ARC_R13, 0, 32 }, + { ARC_R14, 4, 32 }, + { ARC_R15, 8, 32 }, + { ARC_R16, 12, 32 }, + { ARC_R17, 16, 32 }, + { ARC_R18, 20, 32 }, + { ARC_R19, 24, 32 }, + { ARC_R20, 28, 32 }, + { ARC_R21, 32, 32 }, + { ARC_R22, 36, 32 }, + { ARC_R23, 40, 32 }, + { ARC_R24, 44, 32 }, + { ARC_R25, 48, 32 }, + { ARC_GP, 52, 32 }, + { ARC_FP, 56, 32 }, + { ARC_R30, 60, 32 } +}; +static const struct rtos_register_stacking arm_callee_saved_stacking = { + .stack_registers_size = 36, + .stack_growth_direction = -1, + .num_output_registers = ARRAY_SIZE(arm_callee_saved), + .register_offsets = arm_callee_saved, +}; + +static const struct rtos_register_stacking arc_callee_saved_stacking = { + .stack_registers_size = 64, + .stack_growth_direction = -1, + .num_output_registers = ARRAY_SIZE(arc_callee_saved), + .register_offsets = arc_callee_saved, +}; + +static const struct stack_register_offset arm_cpu_saved[] = { + { ARMV7M_R0, 0, 32 }, + { ARMV7M_R1, 4, 32 }, + { ARMV7M_R2, 8, 32 }, + { ARMV7M_R3, 12, 32 }, + { ARMV7M_R4, -1, 32 }, + { ARMV7M_R5, -1, 32 }, + { ARMV7M_R6, -1, 32 }, + { ARMV7M_R7, -1, 32 }, + { ARMV7M_R8, -1, 32 }, + { ARMV7M_R9, -1, 32 }, + { ARMV7M_R10, -1, 32 }, + { ARMV7M_R11, -1, 32 }, + { ARMV7M_R12, 16, 32 }, + { ARMV7M_R13, -2, 32 }, + { ARMV7M_R14, 20, 32 }, + { ARMV7M_PC, 24, 32 }, + { ARMV7M_xPSR, 28, 32 }, +}; + +static struct stack_register_offset arc_cpu_saved[] = { + { ARC_R0, -1, 32 }, + { ARC_R1, -1, 32 }, + { ARC_R2, -1, 32 }, + { ARC_R3, -1, 32 }, + { ARC_R4, -1, 32 }, + { ARC_R5, -1, 32 }, + { ARC_R6, -1, 32 }, + { ARC_R7, -1, 32 }, + { ARC_R8, -1, 32 }, + { ARC_R9, -1, 32 }, + { ARC_R10, -1, 32 }, + { ARC_R11, -1, 32 }, + { ARC_R12, -1, 32 }, + { ARC_R13, -1, 32 }, + { ARC_R14, -1, 32 }, + { ARC_R15, -1, 32 }, + { ARC_R16, -1, 32 }, + { ARC_R17, -1, 32 }, + { ARC_R18, -1, 32 }, + { ARC_R19, -1, 32 }, + { ARC_R20, -1, 32 }, + { ARC_R21, -1, 32 }, + { ARC_R22, -1, 32 }, + { ARC_R23, -1, 32 }, + { ARC_R24, -1, 32 }, + { ARC_R25, -1, 32 }, + { ARC_GP, -1, 32 }, + { ARC_FP, -1, 32 }, + { ARC_SP, -1, 32 }, + { ARC_ILINK, -1, 32 }, + { ARC_R30, -1, 32 }, + { ARC_BLINK, 0, 32 }, + { ARC_LP_COUNT, -1, 32 }, + { ARC_PCL, -1, 32 }, + { ARC_PC, -1, 32 }, + { ARC_LP_START, -1, 32 }, + { ARC_LP_END, -1, 32 }, + { ARC_STATUS32, 4, 32 } +}; + + +enum zephyr_symbol_values { + ZEPHYR_VAL__KERNEL, + ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS, + ZEPHYR_VAL__KERNEL_OPENOCD_SIZE_T_SIZE, + ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS, + ZEPHYR_VAL_COUNT +}; + +static target_addr_t zephyr_cortex_m_stack_align(struct target *target, + const uint8_t *stack_data, + const struct rtos_register_stacking *stacking, target_addr_t stack_ptr) +{ + return rtos_Cortex_M_stack_align(target, stack_data, stacking, + stack_ptr, ARM_XPSR_OFFSET); +} + +static const struct rtos_register_stacking arm_cpu_saved_nofp_stacking = { + .stack_registers_size = 32, + .stack_growth_direction = -1, + .num_output_registers = ARRAY_SIZE(arm_cpu_saved), + .calculate_process_stack = zephyr_cortex_m_stack_align, + .register_offsets = arm_cpu_saved, +}; + +static const struct rtos_register_stacking arm_cpu_saved_fp_stacking = { + .stack_registers_size = 32 + 18 * 4, + .stack_growth_direction = -1, + .num_output_registers = ARRAY_SIZE(arm_cpu_saved), + .calculate_process_stack = zephyr_cortex_m_stack_align, + .register_offsets = arm_cpu_saved, +}; + +/* stack_registers_size is 8 because besides caller registers + * there are only blink and Status32 registers on stack left */ +static struct rtos_register_stacking arc_cpu_saved_stacking = { + .stack_registers_size = 8, + .stack_growth_direction = -1, + .num_output_registers = ARRAY_SIZE(arc_cpu_saved), + .register_offsets = arc_cpu_saved, +}; + +/* ARCv2 specific implementation */ +static int zephyr_get_arc_state(struct rtos *rtos, target_addr_t *addr, + struct zephyr_params *params, + struct rtos_reg *callee_saved_reg_list, + struct rtos_reg **reg_list, int *num_regs) +{ + + uint32_t real_stack_addr; + int retval = 0; + int num_callee_saved_regs; + const struct rtos_register_stacking *stacking; + + /* Getting real stack address from Kernel thread struct */ + retval = target_read_u32(rtos->target, *addr, &real_stack_addr); + if (retval != ERROR_OK) + return retval; + + /* Getting callee registers */ + retval = rtos_generic_stack_read(rtos->target, + params->callee_saved_stacking, + real_stack_addr, &callee_saved_reg_list, + &num_callee_saved_regs); + if (retval != ERROR_OK) + return retval; + + stacking = params->cpu_saved_nofp_stacking; + + /* Getting blink and status32 registers */ + retval = rtos_generic_stack_read(rtos->target, stacking, + real_stack_addr + num_callee_saved_regs * 4, + reg_list, num_regs); + if (retval != ERROR_OK) + return retval; + + for (int i = 0; i < num_callee_saved_regs; i++) + buf_cpy(callee_saved_reg_list[i].value, + (*reg_list)[callee_saved_reg_list[i].number].value, + callee_saved_reg_list[i].size); + + /* The blink, sp, pc offsets in arc_cpu_saved structure may be changed, + * but the registers number shall not. So the next code searches the + * offsetst of these registers in arc_cpu_saved structure. */ + unsigned short blink_offset = 0, pc_offset = 0, sp_offset = 0; + for (size_t i = 0; i < ARRAY_SIZE(arc_cpu_saved); i++) { + if (arc_cpu_saved[i].number == ARC_BLINK) + blink_offset = i; + if (arc_cpu_saved[i].number == ARC_SP) + sp_offset = i; + if (arc_cpu_saved[i].number == ARC_PC) + pc_offset = i; + } + + if (blink_offset == 0 || sp_offset == 0 || pc_offset == 0) { + LOG_ERROR("Basic registers offsets are missing, check <arc_cpu_saved> struct"); + return ERROR_FAIL; + } + + /* Put blink value into PC */ + buf_cpy((*reg_list)[blink_offset].value, + (*reg_list)[pc_offset].value, sizeof((*reg_list)[blink_offset].value)); + + /* Put address after callee/caller in SP. */ + int64_t stack_top; + + stack_top = real_stack_addr + num_callee_saved_regs * 4 + + arc_cpu_saved_stacking.stack_registers_size; + buf_cpy(&stack_top, (*reg_list)[sp_offset].value, sizeof(stack_top)); + + return retval; +} + +/* ARM Cortex-M-specific implementation */ +static int zephyr_get_arm_state(struct rtos *rtos, target_addr_t *addr, + struct zephyr_params *params, + struct rtos_reg *callee_saved_reg_list, + struct rtos_reg **reg_list, int *num_regs) +{ + + int retval = 0; + int num_callee_saved_regs; + const struct rtos_register_stacking *stacking; + + retval = rtos_generic_stack_read(rtos->target, + params->callee_saved_stacking, + *addr, &callee_saved_reg_list, + &num_callee_saved_regs); + if (retval != ERROR_OK) + return retval; + + *addr = target_buffer_get_u32(rtos->target, + callee_saved_reg_list[0].value); + + if (params->offsets[OFFSET_T_PREEMPT_FLOAT] != UNIMPLEMENTED) + stacking = params->cpu_saved_fp_stacking; + else + stacking = params->cpu_saved_nofp_stacking; + + retval = rtos_generic_stack_read(rtos->target, stacking, *addr, reg_list, + num_regs); + if (retval != ERROR_OK) + return retval; + + for (int i = 1; i < num_callee_saved_regs; i++) + buf_cpy(callee_saved_reg_list[i].value, + (*reg_list)[callee_saved_reg_list[i].number].value, + callee_saved_reg_list[i].size); + return 0; +} + +static struct zephyr_params zephyr_params_list[] = { + { + .target_name = "cortex_m", + .pointer_width = 4, + .callee_saved_stacking = &arm_callee_saved_stacking, + .cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking, + .cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking, + .get_cpu_state = &zephyr_get_arm_state, + }, + { + .target_name = "hla_target", + .pointer_width = 4, + .callee_saved_stacking = &arm_callee_saved_stacking, + .cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking, + .cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking, + .get_cpu_state = &zephyr_get_arm_state, + + }, + { + .target_name = "arcv2", + .pointer_width = 4, + .callee_saved_stacking = &arc_callee_saved_stacking, + .cpu_saved_nofp_stacking = &arc_cpu_saved_stacking, + .get_cpu_state = &zephyr_get_arc_state, + }, + { + .target_name = NULL + } +}; + +static const struct symbol_table_elem zephyr_symbol_list[] = { + { + .symbol_name = "_kernel", + .optional = false + }, + { + .symbol_name = "_kernel_openocd_offsets", + .optional = false + }, + { + .symbol_name = "_kernel_openocd_size_t_size", + .optional = false + }, + { + .symbol_name = "_kernel_openocd_num_offsets", + .optional = true + }, + { + .symbol_name = NULL + } +}; + +static bool zephyr_detect_rtos(struct target *target) +{ + if (target->rtos->symbols == NULL) { + LOG_INFO("Zephyr: no symbols while detecting RTOS"); + return false; + } + + for (enum zephyr_symbol_values symbol = ZEPHYR_VAL__KERNEL; + symbol != ZEPHYR_VAL_COUNT; symbol++) { + LOG_INFO("Zephyr: does it have symbol %d (%s)?", symbol, + target->rtos->symbols[symbol].optional ? "optional" : "mandatory"); + + if (target->rtos->symbols[symbol].optional) + continue; + if (target->rtos->symbols[symbol].address == 0) + return false; + } + + LOG_INFO("Zephyr: all mandatory symbols found"); + + return true; +} + +static int zephyr_create(struct target *target) +{ + const char *name; + + name = target_type_name(target); + + LOG_INFO("Zephyr: looking for target: %s", name); + + /* ARC specific, check if EM target has security subsystem + * In case of ARC_HAS_SECURE zephyr option enabled + * the thread stack contains blink,sec_stat,status32 register + * values. If ARC_HAS_SECURE is disabled, only blink and status32 + * register values are saved on stack. */ + if (!strcmp(name, "arcv2")) { + uint32_t value; + struct arc_common *arc = target_to_arc(target); + /* Reading SEC_BUILD bcr */ + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, ARC_AUX_SEC_BUILD_REG, &value)); + if (value != 0) { + LOG_DEBUG("ARC EM board has security subsystem, changing offsets"); + arc_cpu_saved[ARC_REG_NUM - 1].offset = 8; + /* After reading callee registers in stack + * now blink,sec_stat,status32 registers + * are located. */ + arc_cpu_saved_stacking.stack_registers_size = 12; + } + } + + for (struct zephyr_params *p = zephyr_params_list; p->target_name; p++) { + if (!strcmp(p->target_name, name)) { + LOG_INFO("Zephyr: target known, params at %p", p); + target->rtos->rtos_specific_params = p; + return ERROR_OK; + } + } + + LOG_ERROR("Could not find target in Zephyr compatibility list"); + return ERROR_FAIL; +} + +struct zephyr_array { + void *ptr; + size_t elements; +}; + +static void zephyr_array_init(struct zephyr_array *array) +{ + array->ptr = NULL; + array->elements = 0; +} + +static void zephyr_array_free(struct zephyr_array *array) +{ + free(array->ptr); + zephyr_array_init(array); +} + +static void *zephyr_array_append(struct zephyr_array *array, size_t size) +{ + if (!(array->elements % 16)) { + void *ptr = realloc(array->ptr, (array->elements + 16) * size); + + if (!ptr) { + LOG_ERROR("Out of memory"); + return NULL; + } + + array->ptr = ptr; + } + + return (unsigned char *)array->ptr + (array->elements++) * size; +} + +static void *zephyr_array_detach_ptr(struct zephyr_array *array) +{ + void *ptr = array->ptr; + + zephyr_array_init(array); + + return ptr; +} + +static uint32_t zephyr_kptr(const struct rtos *rtos, enum zephyr_offsets off) +{ + const struct zephyr_params *params = rtos->rtos_specific_params; + + return rtos->symbols[ZEPHYR_VAL__KERNEL].address + params->offsets[off]; +} + +static int zephyr_fetch_thread(const struct rtos *rtos, + struct zephyr_thread *thread, uint32_t ptr) +{ + const struct zephyr_params *param = rtos->rtos_specific_params; + int retval; + + thread->ptr = ptr; + + retval = target_read_u32(rtos->target, ptr + param->offsets[OFFSET_T_ENTRY], + &thread->entry); + if (retval != ERROR_OK) + return retval; + + retval = target_read_u32(rtos->target, + ptr + param->offsets[OFFSET_T_NEXT_THREAD], + &thread->next_ptr); + if (retval != ERROR_OK) + return retval; + + retval = target_read_u32(rtos->target, + ptr + param->offsets[OFFSET_T_STACK_POINTER], + &thread->stack_pointer); + if (retval != ERROR_OK) + return retval; + + retval = target_read_u8(rtos->target, ptr + param->offsets[OFFSET_T_STATE], + &thread->state); + if (retval != ERROR_OK) + return retval; + + retval = target_read_u8(rtos->target, + ptr + param->offsets[OFFSET_T_USER_OPTIONS], + &thread->user_options); + if (retval != ERROR_OK) + return retval; + + uint8_t prio; + retval = target_read_u8(rtos->target, + ptr + param->offsets[OFFSET_T_PRIO], &prio); + if (retval != ERROR_OK) + return retval; + thread->prio = prio; + + thread->name[0] = '\0'; + if (param->offsets[OFFSET_T_NAME] != UNIMPLEMENTED) { + retval = target_read_buffer(rtos->target, + ptr + param->offsets[OFFSET_T_NAME], + sizeof(thread->name) - 1, (uint8_t *)thread->name); + if (retval != ERROR_OK) + return retval; + + thread->name[sizeof(thread->name) - 1] = '\0'; + } + + LOG_DEBUG("Fetched thread%" PRIx32 ": {entry@0x%" PRIx32 + ", state=%" PRIu8 ", useropts=%" PRIu8 ", prio=%" PRId8 "}", + ptr, thread->entry, thread->state, thread->user_options, thread->prio); + + return ERROR_OK; +} + +static int zephyr_fetch_thread_list(struct rtos *rtos, uint32_t current_thread) +{ + struct zephyr_array thread_array; + struct zephyr_thread thread; + struct thread_detail *td; + int64_t curr_id = -1; + uint32_t curr; + int retval; + + retval = target_read_u32(rtos->target, zephyr_kptr(rtos, OFFSET_K_THREADS), + &curr); + if (retval != ERROR_OK) { + LOG_ERROR("Could not fetch current thread pointer"); + return retval; + } + + zephyr_array_init(&thread_array); + + for (; curr; curr = thread.next_ptr) { + retval = zephyr_fetch_thread(rtos, &thread, curr); + if (retval != ERROR_OK) + goto error; + + td = zephyr_array_append(&thread_array, sizeof(*td)); + if (!td) + goto error; + + td->threadid = thread.ptr; + td->exists = true; + + if (thread.name[0]) + td->thread_name_str = strdup(thread.name); + else + td->thread_name_str = alloc_printf("thr_%" PRIx32 "_%" PRIx32, + thread.entry, thread.ptr); + td->extra_info_str = alloc_printf("prio:%" PRId8 ",useropts:%" PRIu8, + thread.prio, thread.user_options); + if (!td->thread_name_str || !td->extra_info_str) + goto error; + + if (td->threadid == current_thread) + curr_id = (int64_t)thread_array.elements - 1; + } + + LOG_DEBUG("Got information for %zu threads", thread_array.elements); + + rtos_free_threadlist(rtos); + + rtos->thread_count = (int)thread_array.elements; + rtos->thread_details = zephyr_array_detach_ptr(&thread_array); + + rtos->current_threadid = curr_id; + rtos->current_thread = current_thread; + + return ERROR_OK; + +error: + td = thread_array.ptr; + for (size_t i = 0; i < thread_array.elements; i++) { + free(td[i].thread_name_str); + free(td[i].extra_info_str); + } + + zephyr_array_free(&thread_array); + + return ERROR_FAIL; +} + +static int zephyr_update_threads(struct rtos *rtos) +{ + struct zephyr_params *param; + int retval; + + if (!rtos->rtos_specific_params) + return ERROR_FAIL; + + param = (struct zephyr_params *)rtos->rtos_specific_params; + + if (!rtos->symbols) { + LOG_ERROR("No symbols for Zephyr"); + return ERROR_FAIL; + } + + if (rtos->symbols[ZEPHYR_VAL__KERNEL].address == 0) { + LOG_ERROR("Can't obtain kernel struct from Zephyr"); + return ERROR_FAIL; + } + + if (rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address == 0) { + LOG_ERROR("Please build Zephyr with CONFIG_OPENOCD option set"); + return ERROR_FAIL; + } + + retval = target_read_u8(rtos->target, + rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_SIZE_T_SIZE].address, + ¶m->size_width); + if (retval != ERROR_OK) { + LOG_ERROR("Couldn't determine size of size_t from host"); + return retval; + } + + if (param->size_width != 4) { + LOG_ERROR("Only size_t of 4 bytes are supported"); + return ERROR_FAIL; + } + + if (rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS].address) { + retval = target_read_u32(rtos->target, + rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS].address, + ¶m->num_offsets); + if (retval != ERROR_OK) { + LOG_ERROR("Couldn't not fetch number of offsets from Zephyr"); + return retval; + } + + if (param->num_offsets <= OFFSET_T_STACK_POINTER) { + LOG_ERROR("Number of offsets too small"); + return ERROR_FAIL; + } + } else { + retval = target_read_u32(rtos->target, + rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address, + ¶m->offsets[OFFSET_VERSION]); + if (retval != ERROR_OK) { + LOG_ERROR("Couldn't not fetch offsets from Zephyr"); + return retval; + } + + if (param->offsets[OFFSET_VERSION] > 1) { + LOG_ERROR("Unexpected OpenOCD support version %" PRIu32, + param->offsets[OFFSET_VERSION]); + return ERROR_FAIL; + } + switch (param->offsets[OFFSET_VERSION]) { + case 0: + param->num_offsets = OFFSET_T_STACK_POINTER + 1; + break; + case 1: + param->num_offsets = OFFSET_T_COOP_FLOAT + 1; + break; + } + } + /* We can fetch the whole array for version 0, as they're supposed + * to grow only */ + uint32_t address; + address = rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address; + for (size_t i = 0; i < OFFSET_MAX; i++, address += param->size_width) { + if (i >= param->num_offsets) { + param->offsets[i] = UNIMPLEMENTED; + continue; + } + + retval = target_read_u32(rtos->target, address, ¶m->offsets[i]); + if (retval != ERROR_OK) { + LOG_ERROR("Could not fetch offsets from Zephyr"); + return ERROR_FAIL; + } + } + + LOG_DEBUG("Zephyr OpenOCD support version %" PRId32, + param->offsets[OFFSET_VERSION]); + + uint32_t current_thread; + retval = target_read_u32(rtos->target, + zephyr_kptr(rtos, OFFSET_K_CURR_THREAD), ¤t_thread); + if (retval != ERROR_OK) { + LOG_ERROR("Could not obtain current thread ID"); + return retval; + } + + retval = zephyr_fetch_thread_list(rtos, current_thread); + if (retval != ERROR_OK) { + LOG_ERROR("Could not obtain thread list"); + return retval; + } + + return ERROR_OK; +} + +static int zephyr_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + struct rtos_reg **reg_list, int *num_regs) +{ + struct zephyr_params *params; + struct rtos_reg *callee_saved_reg_list = NULL; + target_addr_t addr; + int retval; + + LOG_INFO("Getting thread %" PRId64 " reg list", thread_id); + + if (rtos == NULL) + return ERROR_FAIL; + + if (thread_id == 0) + return ERROR_FAIL; + + params = rtos->rtos_specific_params; + if (params == NULL) + return ERROR_FAIL; + + addr = thread_id + params->offsets[OFFSET_T_STACK_POINTER] + - params->callee_saved_stacking->register_offsets[0].offset; + + retval = params->get_cpu_state(rtos, &addr, params, callee_saved_reg_list, reg_list, num_regs); + + free(callee_saved_reg_list); + + return retval; +} + +static int zephyr_get_symbol_list_to_lookup(struct symbol_table_elem **symbol_list) +{ + *symbol_list = malloc(sizeof(zephyr_symbol_list)); + if (!*symbol_list) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + memcpy(*symbol_list, zephyr_symbol_list, sizeof(zephyr_symbol_list)); + return ERROR_OK; +} + +struct rtos_type zephyr_rtos = { + .name = "Zephyr", + + .detect_rtos = zephyr_detect_rtos, + .create = zephyr_create, + .update_threads = zephyr_update_threads, + .get_thread_reg_list = zephyr_get_thread_reg_list, + .get_symbol_list_to_lookup = zephyr_get_symbol_list_to_lookup, +}; diff --git a/src/server/Makefile.am b/src/server/Makefile.am index d270ee2..5f7469a 100644 --- a/src/server/Makefile.am +++ b/src/server/Makefile.am @@ -10,7 +10,9 @@ noinst_LTLIBRARIES += %D%/libserver.la %D%/tcl_server.c \ %D%/tcl_server.h \ %D%/rtt_server.c \ - %D%/rtt_server.h + %D%/rtt_server.h \ + %D%/ipdbg.c \ + %D%/ipdbg.h %C%_libserver_la_CFLAGS = $(AM_CFLAGS) if IS_MINGW diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index d9f5d08..fe289c8 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -357,12 +357,50 @@ static int gdb_write(struct connection *connection, void *data, int len) return ERROR_SERVER_REMOTE_CLOSED; } +static void gdb_log_incoming_packet(char *packet) +{ + if (!LOG_LEVEL_IS(LOG_LVL_DEBUG)) + return; + + /* Avoid dumping non-printable characters to the terminal */ + const unsigned packet_len = strlen(packet); + const char *nonprint = find_nonprint_char(packet, packet_len); + if (nonprint) { + /* Does packet at least have a prefix that is printable? + * Look within the first 50 chars of the packet. */ + const char *colon = memchr(packet, ':', MIN(50, packet_len)); + const bool packet_has_prefix = (colon != NULL); + const bool packet_prefix_printable = (packet_has_prefix && nonprint > colon); + + if (packet_prefix_printable) { + const unsigned int prefix_len = colon - packet + 1; /* + 1 to include the ':' */ + const unsigned int payload_len = packet_len - prefix_len; + LOG_DEBUG("received packet: %.*s<binary-data-%u-bytes>", prefix_len, packet, payload_len); + } else { + LOG_DEBUG("received packet: <binary-data-%u-bytes>", packet_len); + } + } else { + /* All chars printable, dump the packet as is */ + LOG_DEBUG("received packet: %s", packet); + } +} + +static void gdb_log_outgoing_packet(char *packet_buf, unsigned int packet_len, unsigned char checksum) +{ + if (!LOG_LEVEL_IS(LOG_LVL_DEBUG)) + return; + + if (find_nonprint_char(packet_buf, packet_len)) + LOG_DEBUG("sending packet: $<binary-data-%u-bytes>#%2.2x", packet_len, checksum); + else + LOG_DEBUG("sending packet: $%.*s#%2.2x'", packet_len, packet_buf, checksum); +} + static int gdb_put_packet_inner(struct connection *connection, char *buffer, int len) { int i; unsigned char my_checksum = 0; - char *debug_buffer; int reply; int retval; struct gdb_connection *gdb_con = connection->priv; @@ -400,9 +438,7 @@ static int gdb_put_packet_inner(struct connection *connection, #endif while (1) { - debug_buffer = strndup(buffer, len); - LOG_DEBUG("sending packet '$%s#%2.2x'", debug_buffer, my_checksum); - free(debug_buffer); + gdb_log_outgoing_packet(buffer, len, my_checksum); char local_buffer[1024]; local_buffer[0] = '$'; @@ -3360,25 +3396,7 @@ static int gdb_input_inner(struct connection *connection) /* terminate with zero */ gdb_packet_buffer[packet_size] = '\0'; - if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) { - char buf[64]; - unsigned offset = 0; - int i = 0; - while (i < packet_size && offset < 56) { - if (packet[i] == '\\') { - buf[offset++] = '\\'; - buf[offset++] = '\\'; - } else if (isprint(packet[i])) { - buf[offset++] = packet[i]; - } else { - sprintf(buf + offset, "\\x%02x", (unsigned char) packet[i]); - offset += 4; - } - i++; - } - buf[offset] = 0; - LOG_DEBUG("received packet: '%s'%s", buf, i < packet_size ? "..." : ""); - } + gdb_log_incoming_packet(gdb_packet_buffer); if (packet_size > 0) { retval = ERROR_OK; @@ -3423,7 +3441,7 @@ static int gdb_input_inner(struct connection *connection) /* '?' is sent after the eventual '!' */ if (!warn_use_ext && !gdb_con->extended_protocol) { warn_use_ext = true; - LOG_WARNING("Prefer GDB command \"target extended-remote %s\" instead of \"target remote %s\"", + LOG_WARNING("Prefer GDB command \"target extended-remote :%s\" instead of \"target remote :%s\"", connection->service->port, connection->service->port); } break; diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c new file mode 100644 index 0000000..ec2fae8 --- /dev/null +++ b/src/server/ipdbg.c @@ -0,0 +1,782 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <helper/bits.h> +#include <helper/time_support.h> +#include <jtag/jtag.h> +#include <server/server.h> +#include <target/target.h> + +#include "ipdbg.h" + +#define IPDBG_BUFFER_SIZE 16384 +#define IPDBG_MIN_NUM_OF_OPTIONS 4 +#define IPDBG_MAX_NUM_OF_OPTIONS 14 +#define IPDBG_MIN_DR_LENGTH 11 +#define IPDBG_MAX_DR_LENGTH 13 +#define IPDBG_TCP_PORT_STR_MAX_LENGTH 6 + +/* private connection data for IPDBG */ +struct ipdbg_fifo { + size_t count; + size_t rd_idx; + char buffer[IPDBG_BUFFER_SIZE]; +}; + +struct ipdbg_connection { + struct ipdbg_fifo dn_fifo; + struct ipdbg_fifo up_fifo; + bool closed; +}; + +struct ipdbg_service { + struct ipdbg_hub *hub; + struct ipdbg_service *next; + uint16_t port; + struct ipdbg_connection connection; + uint8_t tool; +}; + +struct ipdbg_virtual_ir_info { + uint32_t instruction; + uint32_t length; + uint32_t value; +}; + +struct ipdbg_hub { + uint32_t user_instruction; + uint32_t max_tools; + uint32_t active_connections; + uint32_t active_services; + uint32_t valid_mask; + uint32_t xoff_mask; + uint32_t tool_mask; + uint32_t last_dn_tool; + struct ipdbg_hub *next; + struct jtag_tap *tap; + struct connection **connections; + uint8_t data_register_length; + uint8_t dn_xoff; + struct ipdbg_virtual_ir_info *virtual_ir; +}; + +static struct ipdbg_hub *ipdbg_first_hub; + +static struct ipdbg_service *ipdbg_first_service; + +static void ipdbg_init_fifo(struct ipdbg_fifo *fifo) +{ + fifo->count = 0; + fifo->rd_idx = 0; +} + +static bool ipdbg_fifo_is_empty(struct ipdbg_fifo *fifo) +{ + return fifo->count == 0; +} + +static bool ipdbg_fifo_is_full(struct ipdbg_fifo *fifo) +{ + return fifo->count == IPDBG_BUFFER_SIZE; +} + +static void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo) +{ + if (fifo->rd_idx == 0) + return; + + size_t ri = fifo->rd_idx; + for (size_t idx = 0 ; idx < fifo->count ; ++idx) + fifo->buffer[idx] = fifo->buffer[ri++]; + fifo->rd_idx = 0; +} + +static void ipdbg_append_to_fifo(struct ipdbg_fifo *fifo, char data) +{ + if (ipdbg_fifo_is_full(fifo)) + return; + + ipdbg_zero_rd_idx(fifo); + fifo->buffer[fifo->count++] = data; +} + +static char ipdbg_get_from_fifo(struct ipdbg_fifo *fifo) +{ + if (ipdbg_fifo_is_empty(fifo)) + return 0; + + fifo->count--; + return fifo->buffer[fifo->rd_idx++]; +} + +static int ipdbg_move_buffer_to_connection(struct connection *conn, struct ipdbg_fifo *fifo) +{ + if (ipdbg_fifo_is_empty(fifo)) + return ERROR_OK; + + struct ipdbg_connection *connection = conn->priv; + if (connection->closed) + return ERROR_SERVER_REMOTE_CLOSED; + + ipdbg_zero_rd_idx(fifo); + size_t bytes_written = connection_write(conn, fifo->buffer, fifo->count); + if (bytes_written != fifo->count) { + LOG_ERROR("error during write: %zu != %zu", bytes_written, fifo->count); + connection->closed = true; + return ERROR_SERVER_REMOTE_CLOSED; + } + + fifo->count -= bytes_written; + + return ERROR_OK; +} + +static int ipdbg_max_tools_from_data_register_length(uint8_t data_register_length) +{ + int max_tools = 1; + data_register_length -= 10; /* 8 bit payload, 1 xoff-flag, 1 valid-flag; remaining bits used to select tool*/ + while (data_register_length--) + max_tools *= 2; + + /* last tool is used to reset JtagCDC and transfer "XON" to host*/ + return max_tools - 1; +} + +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) { + if (service->hub == hub && service->tool == tool) + break; + } + return service; +} + +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) + ; + iservice->next = service; + } else + ipdbg_first_service = service; +} + +static int ipdbg_create_service(struct ipdbg_hub *hub, uint8_t tool, struct ipdbg_service **service, uint16_t port) +{ + *service = calloc(1, sizeof(struct ipdbg_service)); + if (!*service) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + (*service)->hub = hub; + (*service)->tool = tool; + (*service)->port = port; + + return ERROR_OK; +} + +static int ipdbg_remove_service(struct ipdbg_service *service) +{ + if (!ipdbg_first_service) + return ERROR_FAIL; + + if (service == ipdbg_first_service) { + ipdbg_first_service = ipdbg_first_service->next; + return ERROR_OK; + } + + for (struct ipdbg_service *iservice = ipdbg_first_service ; iservice->next ; iservice = iservice->next) { + if (service == iservice->next) { + iservice->next = service->next; + return ERROR_OK; + } + } + return ERROR_FAIL; +} + +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) { + if (hub->tap == tap && hub->user_instruction == user_instruction) { + if ((!virtual_ir && !hub->virtual_ir) || + (virtual_ir && hub->virtual_ir && + virtual_ir->instruction == hub->virtual_ir->instruction && + virtual_ir->length == hub->virtual_ir->length && + virtual_ir->value == hub->virtual_ir->value)) { + break; + } + } + } + return hub; +} + +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) + ; + ihub->next = hub; + } else + ipdbg_first_hub = hub; +} + +static int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uint8_t data_register_length, + struct ipdbg_virtual_ir_info *virtual_ir, struct ipdbg_hub **hub) +{ + *hub = NULL; + struct ipdbg_hub *new_hub = calloc(1, sizeof(struct ipdbg_hub)); + if (!new_hub) { + free(virtual_ir); + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + new_hub->max_tools = ipdbg_max_tools_from_data_register_length(data_register_length); + new_hub->connections = calloc(new_hub->max_tools, sizeof(struct connection *)); + if (!new_hub->connections) { + free(virtual_ir); + free(new_hub); + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + new_hub->tap = tap; + new_hub->user_instruction = user_instruction; + new_hub->data_register_length = data_register_length; + new_hub->valid_mask = BIT(data_register_length - 1); + new_hub->xoff_mask = BIT(data_register_length - 2); + new_hub->tool_mask = (new_hub->xoff_mask - 1) >> 8; + new_hub->last_dn_tool = new_hub->tool_mask; + new_hub->virtual_ir = virtual_ir; + + *hub = new_hub; + + return ERROR_OK; +} + +static void ipdbg_free_hub(struct ipdbg_hub *hub) +{ + if (!hub) + return; + free(hub->connections); + free(hub->virtual_ir); + free(hub); +} + +static int ipdbg_remove_hub(struct ipdbg_hub *hub) +{ + if (!ipdbg_first_hub) + return ERROR_FAIL; + if (hub == ipdbg_first_hub) { + ipdbg_first_hub = ipdbg_first_hub->next; + return ERROR_OK; + } + + for (struct ipdbg_hub *ihub = ipdbg_first_hub ; ihub->next ; ihub = ihub->next) { + if (hub == ihub->next) { + ihub->next = hub->next; + return ERROR_OK; + } + } + + return ERROR_FAIL; +} + +static void ipdbg_init_scan_field(struct scan_field *fields, uint8_t *in_value, int num_bits, const uint8_t *out_value) +{ + fields->check_mask = NULL; + fields->check_value = NULL; + fields->in_value = in_value; + fields->num_bits = num_bits; + fields->out_value = out_value; +} + +static int ipdbg_shift_instr(struct ipdbg_hub *hub, uint32_t instr) +{ + if (!hub) + return ERROR_FAIL; + + struct jtag_tap *tap = hub->tap; + if (!tap) + return ERROR_FAIL; + + if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == instr) { + /* there is already the requested instruction in the ir */ + return ERROR_OK; + } + + uint8_t *ir_out_val = calloc(DIV_ROUND_UP(tap->ir_length, 8), 1); + buf_set_u32(ir_out_val, 0, tap->ir_length, instr); + + struct scan_field fields; + ipdbg_init_scan_field(&fields, NULL, tap->ir_length, ir_out_val); + jtag_add_ir_scan(tap, &fields, TAP_IDLE); + int retval = jtag_execute_queue(); + + free(ir_out_val); + + return retval; +} + +static int ipdbg_shift_vir(struct ipdbg_hub *hub) +{ + if (!hub) + return ERROR_FAIL; + + if (!hub->virtual_ir) + return ERROR_OK; + + int retval = ipdbg_shift_instr(hub, hub->virtual_ir->instruction); + if (retval != ERROR_OK) + return retval; + + struct jtag_tap *tap = hub->tap; + if (!tap) + return ERROR_FAIL; + + uint8_t *dr_out_val = calloc(DIV_ROUND_UP(hub->virtual_ir->length, 8), 1); + buf_set_u32(dr_out_val, 0, hub->virtual_ir->length, hub->virtual_ir->value); + + struct scan_field fields; + ipdbg_init_scan_field(&fields, NULL, hub->virtual_ir->length, dr_out_val); + jtag_add_dr_scan(tap, 1, &fields, TAP_IDLE); + retval = jtag_execute_queue(); + + free(dr_out_val); + + return retval; +} + +static int ipdbg_shift_data(struct ipdbg_hub *hub, uint32_t dn_data, uint32_t *up_data) +{ + if (!hub) + return ERROR_FAIL; + + struct jtag_tap *tap = hub->tap; + if (!tap) + return ERROR_FAIL; + + uint8_t *dr_out_val = calloc(DIV_ROUND_UP(hub->data_register_length, 8), 1); + buf_set_u32(dr_out_val, 0, hub->data_register_length, dn_data); + uint8_t *dr_in_val = up_data ? calloc(DIV_ROUND_UP(hub->data_register_length, 8), 1) : NULL; + + struct scan_field fields; + ipdbg_init_scan_field(&fields, dr_in_val, hub->data_register_length, dr_out_val); + jtag_add_dr_scan(tap, 1, &fields, TAP_IDLE); + int retval = jtag_execute_queue(); + + if (up_data && retval == ERROR_OK) + *up_data = buf_get_u32(dr_in_val, 0, hub->data_register_length); + + free(dr_out_val); + free(dr_in_val); + + return retval; +} + +static int ipdbg_distribute_data_from_hub(struct ipdbg_hub *hub, uint32_t up) +{ + const bool valid_up_data = up & hub->valid_mask; + if (!valid_up_data) + return ERROR_OK; + + const size_t tool = (up >> 8) & hub->tool_mask; + if (tool == hub->tool_mask) { + const uint8_t xon_cmd = up & 0x00ff; + hub->dn_xoff &= ~xon_cmd; + LOG_INFO("received xon cmd: %d\n", xon_cmd); + return ERROR_OK; + } + + struct connection *conn = hub->connections[tool]; + if (conn) { + struct ipdbg_connection *connection = conn->priv; + if (ipdbg_fifo_is_full(&connection->up_fifo)) { + int retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo); + if (retval != ERROR_OK) + return retval; + } + ipdbg_append_to_fifo(&connection->up_fifo, up); + } + return ERROR_OK; +} + +static int ipdbg_jtag_transfer_byte(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection) +{ + uint32_t dn = hub->valid_mask | ((tool & hub->tool_mask) << 8) | + (0x00fful & ipdbg_get_from_fifo(&connection->dn_fifo)); + uint32_t up = 0; + int ret = ipdbg_shift_data(hub, dn, &up); + if (ret != ERROR_OK) + return ret; + + ret = ipdbg_distribute_data_from_hub(hub, up); + if (ret != ERROR_OK) + return ret; + + if ((up & hub->xoff_mask) && (hub->last_dn_tool != hub->max_tools)) { + hub->dn_xoff |= BIT(hub->last_dn_tool); + LOG_INFO("tool %d sent xoff", hub->last_dn_tool); + } + + hub->last_dn_tool = tool; + + return ERROR_OK; +} + +static int ipdbg_polling_callback(void *priv) +{ + struct ipdbg_hub *hub = priv; + + int ret = ipdbg_shift_vir(hub); + if (ret != ERROR_OK) + return ret; + + ret = ipdbg_shift_instr(hub, hub->user_instruction); + if (ret != ERROR_OK) + return ret; + + /* transfer dn buffers to jtag-hub */ + unsigned int num_transfers = 0; + 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; + while (((hub->dn_xoff & BIT(tool)) == 0) && !ipdbg_fifo_is_empty(&connection->dn_fifo)) { + ret = ipdbg_jtag_transfer_byte(hub, tool, connection); + if (ret != ERROR_OK) + return ret; + ++num_transfers; + } + } + } + + /* some transfers to get data from jtag-hub in case there is no dn data */ + while (num_transfers++ < hub->max_tools) { + uint32_t dn = 0; + uint32_t up = 0; + + int retval = ipdbg_shift_data(hub, dn, &up); + if (retval != ERROR_OK) + return ret; + + retval = ipdbg_distribute_data_from_hub(hub, up); + if (retval != ERROR_OK) + return ret; + } + + /* write from up fifos to sockets */ + 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; + int retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo); + if (retval != ERROR_OK) + return retval; + } + } + + return ERROR_OK; +} + +static int ipdbg_start_polling(struct ipdbg_service *service, struct connection *connection) +{ + struct ipdbg_hub *hub = service->hub; + hub->connections[service->tool] = connection; + hub->active_connections++; + if (hub->active_connections > 1) { + /* hub is already initialized */ + return ERROR_OK; + } + + const uint32_t reset_hub = hub->valid_mask | ((hub->max_tools) << 8); + + int ret = ipdbg_shift_vir(hub); + if (ret != ERROR_OK) + return ret; + + ret = ipdbg_shift_instr(hub, hub->user_instruction); + if (ret != ERROR_OK) + return ret; + + ret = ipdbg_shift_data(hub, reset_hub, NULL); + hub->last_dn_tool = hub->tool_mask; + hub->dn_xoff = 0; + if (ret != ERROR_OK) + return ret; + + LOG_INFO("IPDBG start_polling"); + + const int time_ms = 20; + const int periodic = 1; + return target_register_timer_callback(ipdbg_polling_callback, time_ms, periodic, hub); +} + +static int ipdbg_stop_polling(struct ipdbg_service *service) +{ + struct ipdbg_hub *hub = service->hub; + hub->connections[service->tool] = NULL; + hub->active_connections--; + if (hub->active_connections == 0) { + LOG_INFO("IPDBG stop_polling"); + + return target_unregister_timer_callback(ipdbg_polling_callback, hub); + } + + return ERROR_OK; +} + +static int ipdbg_on_new_connection(struct connection *connection) +{ + struct ipdbg_service *service = connection->service->priv; + connection->priv = &service->connection; + /* initialize ipdbg connection information */ + ipdbg_init_fifo(&service->connection.up_fifo); + ipdbg_init_fifo(&service->connection.dn_fifo); + + int retval = ipdbg_start_polling(service, connection); + if (retval != ERROR_OK) { + LOG_ERROR("BUG: ipdbg_start_polling failed"); + return retval; + } + + struct ipdbg_connection *conn = connection->priv; + conn->closed = false; + + LOG_INFO("New IPDBG Connection"); + + return ERROR_OK; +} + +static int ipdbg_on_connection_input(struct connection *connection) +{ + struct ipdbg_connection *conn = connection->priv; + struct ipdbg_fifo *fifo = &conn->dn_fifo; + + if (ipdbg_fifo_is_full(fifo)) + return ERROR_OK; + + ipdbg_zero_rd_idx(fifo); + int bytes_read = connection_read(connection, fifo->buffer + fifo->count, IPDBG_BUFFER_SIZE - fifo->count); + if (bytes_read <= 0) { + if (bytes_read < 0) + LOG_ERROR("error during read: %s", strerror(errno)); + return ERROR_SERVER_REMOTE_CLOSED; + } + + fifo->count += bytes_read; + + return ERROR_OK; +} + +static int ipdbg_on_connection_closed(struct connection *connection) +{ + struct ipdbg_connection *conn = connection->priv; + conn->closed = true; + LOG_INFO("Closed IPDBG Connection"); + + return ipdbg_stop_polling(connection->service->priv); +} + +static int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t user_instruction, + uint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool) +{ + LOG_INFO("starting ipdbg service on port %d for tool %d", port, tool); + + struct ipdbg_hub *hub = ipdbg_find_hub(tap, user_instruction, virtual_ir); + if (hub) { + free(virtual_ir); + if (hub->data_register_length != data_register_length) { + LOG_DEBUG("hub must have the same data_register_length for all tools"); + return ERROR_FAIL; + } + } else { + int retval = ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, &hub); + if (retval != ERROR_OK) { + free(virtual_ir); + return retval; + } + } + + struct ipdbg_service *service = NULL; + int retval = ipdbg_create_service(hub, tool, &service, port); + + if (retval != ERROR_OK || !service) { + if (hub->active_services == 0 && hub->active_connections == 0) + ipdbg_free_hub(hub); + return ERROR_FAIL; + } + + char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH]; + snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", port); + retval = add_service("ipdbg", port_str_buffer, 1, &ipdbg_on_new_connection, + &ipdbg_on_connection_input, &ipdbg_on_connection_closed, service); + if (retval == ERROR_OK) { + ipdbg_add_service(service); + if (hub->active_services == 0 && hub->active_connections == 0) + ipdbg_add_hub(hub); + hub->active_services++; + } else { + if (hub->active_services == 0 && hub->active_connections == 0) + ipdbg_free_hub(hub); + free(service); + } + + return retval; +} + +static int ipdbg_stop(struct jtag_tap *tap, uint32_t user_instruction, + struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool) +{ + struct ipdbg_hub *hub = ipdbg_find_hub(tap, user_instruction, virtual_ir); + free(virtual_ir); + if (!hub) + return ERROR_FAIL; + + struct ipdbg_service *service = ipdbg_find_service(hub, tool); + if (!service) + return ERROR_FAIL; + + int retval = ipdbg_remove_service(service); + if (retval != ERROR_OK) { + LOG_ERROR("BUG: ipdbg_remove_service failed"); + return retval; + } + + char port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH]; + snprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, "%u", service->port); + retval = remove_service("ipdbg", port_str_buffer); + /* The ipdbg_service structure is freed by server.c:remove_service(). + There the "priv" pointer is freed.*/ + if (retval != ERROR_OK) { + LOG_ERROR("BUG: remove_service failed"); + return retval; + } + hub->active_services--; + if (hub->active_connections == 0 && hub->active_services == 0) { + retval = ipdbg_remove_hub(hub); + if (retval != ERROR_OK) { + LOG_ERROR("BUG: ipdbg_remove_hub failed"); + return retval; + } + ipdbg_free_hub(hub); + } + return ERROR_OK; +} + +COMMAND_HANDLER(handle_ipdbg_command) +{ + struct jtag_tap *tap = NULL; + uint16_t port = 4242; + uint8_t tool = 1; + uint32_t user_instruction = 0x00; + uint8_t data_register_length = IPDBG_MAX_DR_LENGTH; + bool start = true; + bool hub_configured = false; + bool has_virtual_ir = false; + uint32_t virtual_ir_instruction = 0x00e; + uint32_t virtual_ir_length = 5; + uint32_t virtual_ir_value = 0x11; + struct ipdbg_virtual_ir_info *virtual_ir = NULL; + + if ((CMD_ARGC < IPDBG_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > IPDBG_MAX_NUM_OF_OPTIONS)) + return ERROR_COMMAND_SYNTAX_ERROR; + + for (unsigned int i = 0; i < CMD_ARGC; ++i) { + if (strcmp(CMD_ARGV[i], "-tap") == 0) { + if (i + 1 >= CMD_ARGC || CMD_ARGV[i + 1][0] == '-') { + command_print(CMD, "no TAP given"); + return ERROR_FAIL; + } + tap = jtag_tap_by_string(CMD_ARGV[i + 1]); + if (!tap) { + command_print(CMD, "Tap %s unknown", CMD_ARGV[i + 1]); + return ERROR_FAIL; + } + ++i; + } else if (strcmp(CMD_ARGV[i], "-hub") == 0) { + COMMAND_PARSE_ADDITIONAL_NUMBER(u32, i, user_instruction, "ir_value to select hub"); + hub_configured = true; + COMMAND_PARSE_OPTIONAL_NUMBER(u8, i, data_register_length); + if (data_register_length < IPDBG_MIN_DR_LENGTH || + data_register_length > IPDBG_MAX_DR_LENGTH) { + command_print(CMD, "length of \"user\"-data register must be at least %d and at most %d.", + IPDBG_MIN_DR_LENGTH, IPDBG_MAX_DR_LENGTH); + return ERROR_FAIL; + } + } else if (strcmp(CMD_ARGV[i], "-vir") == 0) { + COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_value); + COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_length); + COMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_instruction); + has_virtual_ir = true; + } else if (strcmp(CMD_ARGV[i], "-port") == 0) { + COMMAND_PARSE_ADDITIONAL_NUMBER(u16, i, port, "port number"); + } else if (strcmp(CMD_ARGV[i], "-tool") == 0) { + COMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, tool, "tool"); + } else if (strcmp(CMD_ARGV[i], "-stop") == 0) { + start = false; + } else if (strcmp(CMD_ARGV[i], "-start") == 0) { + start = true; + } else { + command_print(CMD, "Unknown argument: %s", CMD_ARGV[i]); + return ERROR_FAIL; + } + } + + if (!tap) { + command_print(CMD, "no valid tap selected"); + return ERROR_FAIL; + } + + if (!hub_configured) { + command_print(CMD, "hub not configured correctly"); + return ERROR_FAIL; + } + + if (tool >= ipdbg_max_tools_from_data_register_length(data_register_length)) { + command_print(CMD, "Tool: %d is invalid", tool); + return ERROR_FAIL; + } + + if (has_virtual_ir) { + virtual_ir = calloc(1, sizeof(struct ipdbg_virtual_ir_info)); + if (!virtual_ir) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + virtual_ir->instruction = virtual_ir_instruction; + virtual_ir->length = virtual_ir_length; + virtual_ir->value = virtual_ir_value; + } + + if (start) + return ipdbg_start(port, tap, user_instruction, data_register_length, virtual_ir, tool); + else + return ipdbg_stop(tap, user_instruction, virtual_ir, tool); +} + +static const struct command_registration ipdbg_command_handlers[] = { + { + .name = "ipdbg", + .handler = handle_ipdbg_command, + .mode = COMMAND_EXEC, + .help = "Starts or stops an IPDBG JTAG-Host server.", + .usage = "[-start|-stop] -tap device.tap -hub ir_value [dr_length]" + " [-port number] [-tool number] [-vir [vir_value [length [instr_code]]]]", + }, + COMMAND_REGISTRATION_DONE +}; + +int ipdbg_register_commands(struct command_context *cmd_ctx) +{ + return register_commands(cmd_ctx, NULL, ipdbg_command_handlers); +} diff --git a/src/server/ipdbg.h b/src/server/ipdbg.h new file mode 100644 index 0000000..6b70545 --- /dev/null +++ b/src/server/ipdbg.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */ + +#ifndef OPENOCD_IPDBG_IPDBG_H +#define OPENOCD_IPDBG_IPDBG_H + +#include <helper/command.h> + +int ipdbg_register_commands(struct command_context *cmd_ctx); + +#endif /* OPENOCD_IPDBG_IPDBG_H */ diff --git a/src/server/startup.tcl b/src/server/startup.tcl index dd1b31e..447b57c 100644 --- a/src/server/startup.tcl +++ b/src/server/startup.tcl @@ -9,6 +9,9 @@ proc ocd_gdb_restart {target_id} { reset halt } +lappend _telnet_autocomplete_skip prevent_cps +lappend _telnet_autocomplete_skip POST +lappend _telnet_autocomplete_skip Host: proc prevent_cps {} { echo "Possible SECURITY ATTACK detected." echo "It looks like somebody is sending POST or Host: commands to OpenOCD." @@ -19,3 +22,20 @@ proc prevent_cps {} { proc POST {args} { prevent_cps } proc Host: {args} { prevent_cps } + +# list of commands we don't want to appear in autocomplete +lappend _telnet_autocomplete_skip _telnet_autocomplete_helper + +# helper for telnet autocomplete +proc _telnet_autocomplete_helper pattern { + set cmds [info commands $pattern] + + # skip matches in variable '_telnet_autocomplete_skip' + foreach skip $::_telnet_autocomplete_skip { + foreach n [lsearch -all -regexp $cmds "^$skip\$"] { + set cmds [lreplace $cmds $n $n] + } + } + + return [lsort $cmds] +} diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c index d5e0353..2ad3791 100644 --- a/src/server/telnet_server.c +++ b/src/server/telnet_server.c @@ -470,7 +470,7 @@ static void telnet_auto_complete(struct connection *connection) query[usr_cmd_len] = '\0'; /* filter commands */ - char *query_cmd = alloc_printf("lsort [info commands {%s*}]", query); + char *query_cmd = alloc_printf("_telnet_autocomplete_helper {%s*}", query); if (!query_cmd) { LOG_ERROR("Out of memory"); @@ -500,22 +500,18 @@ static void telnet_auto_complete(struct connection *connection) bool ignore_cmd = false; Jim_Cmd *jim_cmd = Jim_GetCommand(command_context->interp, elem, JIM_NONE); - if (!jim_cmd) + if (!jim_cmd) { + /* Why we are here? Let's ignore it! */ ignore_cmd = true; - else { - if (!jim_cmd->isproc) { - /* ignore commands without handler - * and those with COMMAND_CONFIG mode */ - /* FIXME it's better to use jimcmd_is_ocd_command(jim_cmd) - * or command_find_from_name(command_context->interp, name) */ - struct command *cmd = jim_cmd->u.native.privData; - if (!cmd) - ignore_cmd = true; - /* make Valgrind happy by checking that cmd is not NULL */ - else if (cmd != NULL && !cmd->handler && !cmd->jim_handler) - ignore_cmd = true; - else if (cmd != NULL && cmd->mode == COMMAND_CONFIG) - ignore_cmd = true; + } else if (jimcmd_is_oocd_command(jim_cmd)) { + struct command *cmd = jimcmd_privdata(jim_cmd); + + if (cmd && !cmd->handler && !cmd->jim_handler) { + /* Initial part of a multi-word command. Ignore it! */ + ignore_cmd = true; + } else if (cmd && cmd->mode == COMMAND_CONFIG) { + /* Not executable after config phase. Ignore it! */ + ignore_cmd = true; } } diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 4ba92c8..ef00fd1 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -988,25 +988,26 @@ static int aarch64_debug_entry(struct target *target) /* Examine debug reason */ armv8_dpm_report_dscr(dpm, dscr); - /* save address of instruction that triggered the watchpoint? */ + /* save the memory address that triggered the watchpoint */ if (target->debug_reason == DBG_REASON_WATCHPOINT) { uint32_t tmp; - uint64_t wfar = 0; retval = mem_ap_read_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_WFAR1, - &tmp); + armv8->debug_base + CPUV8_DBG_EDWAR0, &tmp); if (retval != ERROR_OK) return retval; - wfar = tmp; - wfar = (wfar << 32); - retval = mem_ap_read_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_WFAR0, - &tmp); - if (retval != ERROR_OK) - return retval; - wfar |= tmp; - armv8_dpm_report_wfar(&armv8->dpm, wfar); + target_addr_t edwar = tmp; + + /* EDWAR[63:32] has unknown content in aarch32 state */ + if (core_state == ARM_STATE_AARCH64) { + retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_EDWAR1, &tmp); + if (retval != ERROR_OK) + return retval; + edwar |= ((target_addr_t)tmp) << 32; + } + + armv8->dpm.wp_addr = edwar; } retval = armv8_dpm_read_current_registers(&armv8->dpm); @@ -1853,31 +1854,19 @@ int aarch64_hit_watchpoint(struct target *target, struct armv8_common *armv8 = target_to_armv8(target); - uint64_t exception_address; + target_addr_t exception_address; struct watchpoint *wp; - exception_address = armv8->dpm.wp_pc; + exception_address = armv8->dpm.wp_addr; if (exception_address == 0xFFFFFFFF) return ERROR_FAIL; - /**********************************************************/ - /* see if a watchpoint address matches a value read from */ - /* the EDWAR register. Testing shows that on some ARM CPUs*/ - /* the EDWAR value needs to have 8 added to it so we add */ - /* that check as well not sure if that is a core bug) */ - /**********************************************************/ - for (exception_address = armv8->dpm.wp_pc; exception_address <= (armv8->dpm.wp_pc + 8); - exception_address += 8) { - for (wp = target->watchpoints; wp; wp = wp->next) { - if ((exception_address >= wp->address) && (exception_address < (wp->address + wp->length))) { - *hit_watchpoint = wp; - if (exception_address != armv8->dpm.wp_pc) - LOG_DEBUG("watchpoint hit required EDWAR to be increased by 8"); - return ERROR_OK; - } + for (wp = target->watchpoints; wp; wp = wp->next) + if (exception_address >= wp->address && exception_address < (wp->address + wp->length)) { + *hit_watchpoint = wp; + return ERROR_OK; } - } return ERROR_FAIL; } @@ -2796,15 +2785,15 @@ enum aarch64_cfg_param { CFG_CTI, }; -static const Jim_Nvp nvp_config_opts[] = { +static const struct jim_nvp nvp_config_opts[] = { { .name = "-cti", .value = CFG_CTI }, { .name = NULL, .value = -1 } }; -static int aarch64_jim_configure(struct target *target, Jim_GetOptInfo *goi) +static int aarch64_jim_configure(struct target *target, struct jim_getopt_info *goi) { struct aarch64_private_config *pc; - Jim_Nvp *n; + struct jim_nvp *n; int e; pc = (struct aarch64_private_config *)target->private_config; @@ -2835,12 +2824,12 @@ static int aarch64_jim_configure(struct target *target, Jim_GetOptInfo *goi) Jim_SetEmptyResult(goi->interp); /* check first if topmost item is for us */ - e = Jim_Nvp_name2value_obj(goi->interp, nvp_config_opts, + e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts, goi->argv[0], &n); if (e != JIM_OK) return JIM_CONTINUE; - e = Jim_GetOpt_Obj(goi, NULL); + e = jim_getopt_obj(goi, NULL); if (e != JIM_OK) return e; @@ -2849,7 +2838,7 @@ static int aarch64_jim_configure(struct target *target, Jim_GetOptInfo *goi) if (goi->isconfigure) { Jim_Obj *o_cti; struct arm_cti *cti; - e = Jim_GetOpt_Obj(goi, &o_cti); + e = jim_getopt_obj(goi, &o_cti); if (e != JIM_OK) return e; cti = cti_instance_by_jim_obj(goi->interp, o_cti); @@ -2941,15 +2930,15 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) struct target *target = get_current_target(CMD_CTX); struct aarch64_common *aarch64 = target_to_aarch64(target); - static const Jim_Nvp nvp_maskisr_modes[] = { + static const struct jim_nvp nvp_maskisr_modes[] = { { .name = "off", .value = AARCH64_ISRMASK_OFF }, { .name = "on", .value = AARCH64_ISRMASK_ON }, { .name = NULL, .value = -1 }, }; - const Jim_Nvp *n; + const struct jim_nvp *n; if (CMD_ARGC > 0) { - n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]); + n = jim_nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]); if (n->name == NULL) { LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]); return ERROR_COMMAND_SYNTAX_ERROR; @@ -2958,7 +2947,7 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) aarch64->isrmasking_mode = n->value; } - n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, aarch64->isrmasking_mode); + n = jim_nvp_value2name_simple(nvp_maskisr_modes, aarch64->isrmasking_mode); command_print(CMD, "aarch64 interrupt mask %s", n->name); return ERROR_OK; diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c index 6dede97..239253d 100644 --- a/src/target/adi_v5_jtag.c +++ b/src/target/adi_v5_jtag.c @@ -574,6 +574,13 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) retval = ERROR_JTAG_DEVICE_ERROR; break; } + LOG_INFO("DAP transaction stalled during replay (WAIT) - resending"); + /* clear the sticky overrun condition */ + retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC, + DP_CTRL_STAT, DPAP_WRITE, + dap->dp_ctrl_stat | SSTICKYORUN, NULL, 0); + if (retval != ERROR_OK) + break; } while (timeval_ms() - time_now < 1000); if (retval == ERROR_OK) { diff --git a/src/target/arc.c b/src/target/arc.c index 694ac6f..e11cd7d 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -1467,7 +1467,7 @@ static int arc_configure_actionpoint(struct target *target, uint32_t ap_num, if (control_tt != AP_AC_TT_DISABLE) { if (arc->actionpoints_num_avail < 1) { - LOG_ERROR("No free actionpoints, maximim amount is %u", + LOG_ERROR("No free actionpoints, maximum amount is %u", arc->actionpoints_num); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } diff --git a/src/target/arc.h b/src/target/arc.h index 8d44bfa..f0351bd 100644 --- a/src/target/arc.h +++ b/src/target/arc.h @@ -206,7 +206,7 @@ struct arc_common { bool dcache_invalidated; bool l2cache_invalidated; - /* Indicate if cach was built (for deinit function) */ + /* Indicate if cache was built (for deinit function) */ bool core_aux_cache_built; bool bcr_cache_built; /* Closely Coupled memory(CCM) regions for performance-critical diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c index 5c5247b..26c67c6 100644 --- a/src/target/arc_cmd.c +++ b/src/target/arc_cmd.c @@ -22,10 +22,10 @@ * ------------------------------------------------------------------------- */ -static int arc_cmd_jim_get_uint32(Jim_GetOptInfo *goi, uint32_t *value) +static int arc_cmd_jim_get_uint32(struct jim_getopt_info *goi, uint32_t *value) { jim_wide value_wide; - JIM_CHECK_RETVAL(Jim_GetOpt_Wide(goi, &value_wide)); + JIM_CHECK_RETVAL(jim_getopt_wide(goi, &value_wide)); *value = (uint32_t)value_wide; return JIM_OK; } @@ -40,7 +40,7 @@ enum add_reg_type_flags { CFG_ADD_REG_TYPE_FLAGS_FLAG, }; -static Jim_Nvp nvp_add_reg_type_flags_opts[] = { +static struct jim_nvp nvp_add_reg_type_flags_opts[] = { { .name = "-name", .value = CFG_ADD_REG_TYPE_FLAGS_NAME }, { .name = "-flag", .value = CFG_ADD_REG_TYPE_FLAGS_FLAG }, { .name = NULL, .value = -1 } @@ -64,7 +64,7 @@ static const char *validate_register(const struct arc_reg_desc * const reg, bool /* Helper function to read the name of register type or register from * configure files */ -static int jim_arc_read_reg_name_field(Jim_GetOptInfo *goi, +static int jim_arc_read_reg_name_field(struct jim_getopt_info *goi, const char **name, int *name_len) { int e = JIM_OK; @@ -73,12 +73,12 @@ static int jim_arc_read_reg_name_field(Jim_GetOptInfo *goi, Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-name <name> ..."); return JIM_ERR; } - e = Jim_GetOpt_String(goi, name, name_len); + e = jim_getopt_string(goi, name, name_len); return e; } /* Helper function to read bitfields/flags of register type. */ -static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_name, int *field_name_len, +static int jim_arc_read_reg_type_field(struct jim_getopt_info *goi, const char **field_name, int *field_name_len, struct arc_reg_bitfield *bitfields, int cur_field, int type) { jim_wide start_pos, end_pos; @@ -90,12 +90,12 @@ static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_n return JIM_ERR; } - e = Jim_GetOpt_String(goi, field_name, field_name_len); + e = jim_getopt_string(goi, field_name, field_name_len); if (e != JIM_OK) return e; /* read start position of bitfield/flag */ - e = Jim_GetOpt_Wide(goi, &start_pos); + e = jim_getopt_wide(goi, &start_pos); if (e != JIM_OK) return e; @@ -108,7 +108,7 @@ static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_n * than bitfields[cur_field].end remains start */ if ((strcmp(Jim_String(goi->argv[0]), "-flag") && type == CFG_ADD_REG_TYPE_FLAG) || (type == CFG_ADD_REG_TYPE_STRUCT)) { - e = Jim_GetOpt_Wide(goi, &end_pos); + e = jim_getopt_wide(goi, &end_pos); if (e != JIM_OK) { Jim_SetResultFormatted(goi->interp, "Error reading end position"); return e; @@ -125,8 +125,8 @@ static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_n static int jim_arc_add_reg_type_flags(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { - Jim_GetOptInfo goi; - JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + struct jim_getopt_info goi; + JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); LOG_DEBUG("-"); @@ -179,10 +179,10 @@ static int jim_arc_add_reg_type_flags(Jim_Interp *interp, int argc, flags->size = 4; /* For now ARC has only 32-bit registers */ while (goi.argc > 0 && e == JIM_OK) { - Jim_Nvp *n; - e = Jim_GetOpt_Nvp(&goi, nvp_add_reg_type_flags_opts, &n); + struct jim_nvp *n; + e = jim_getopt_nvp(&goi, nvp_add_reg_type_flags_opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(&goi, nvp_add_reg_type_flags_opts, 0); + jim_getopt_nvp_unknown(&goi, nvp_add_reg_type_flags_opts, 0); continue; } @@ -272,7 +272,7 @@ enum add_reg_type_struct { CFG_ADD_REG_TYPE_STRUCT_BITFIELD, }; -static Jim_Nvp nvp_add_reg_type_struct_opts[] = { +static struct jim_nvp nvp_add_reg_type_struct_opts[] = { { .name = "-name", .value = CFG_ADD_REG_TYPE_STRUCT_NAME }, { .name = "-bitfield", .value = CFG_ADD_REG_TYPE_STRUCT_BITFIELD }, { .name = NULL, .value = -1 } @@ -286,8 +286,8 @@ static int jim_arc_set_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *ar uint32_t regnum; uint32_t value; - Jim_GetOptInfo goi; - JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + struct jim_getopt_info goi; + JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); if (goi.argc != 2) { Jim_SetResultFormatted(goi.interp, @@ -325,8 +325,8 @@ static int jim_arc_get_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *ar uint32_t regnum; uint32_t value; - Jim_GetOptInfo goi; - JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + struct jim_getopt_info goi; + JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); if (goi.argc != 1) { Jim_SetResultFormatted(goi.interp, @@ -362,8 +362,8 @@ static int jim_arc_get_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *a uint32_t regnum; uint32_t value; - Jim_GetOptInfo goi; - JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + struct jim_getopt_info goi; + JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); if (goi.argc != 1) { Jim_SetResultFormatted(goi.interp, @@ -405,8 +405,8 @@ static int jim_arc_set_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *a uint32_t regnum; uint32_t value; - Jim_GetOptInfo goi; - JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + struct jim_getopt_info goi; + JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); if (goi.argc != 2) { Jim_SetResultFormatted(goi.interp, @@ -491,8 +491,8 @@ static const struct command_registration arc_jtag_command_group[] = { static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { - Jim_GetOptInfo goi; - JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + struct jim_getopt_info goi; + JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); LOG_DEBUG("-"); @@ -545,10 +545,10 @@ static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc, struct_type->size = 4; /* For now ARC has only 32-bit registers */ while (goi.argc > 0 && e == JIM_OK) { - Jim_Nvp *n; - e = Jim_GetOpt_Nvp(&goi, nvp_add_reg_type_struct_opts, &n); + struct jim_nvp *n; + e = jim_getopt_nvp(&goi, nvp_add_reg_type_struct_opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(&goi, nvp_add_reg_type_struct_opts, 0); + jim_getopt_nvp_unknown(&goi, nvp_add_reg_type_struct_opts, 0); continue; } @@ -642,7 +642,7 @@ enum opts_add_reg { CFG_ADD_REG_GENERAL, }; -static Jim_Nvp opts_nvp_add_reg[] = { +static struct jim_nvp opts_nvp_add_reg[] = { { .name = "-name", .value = CFG_ADD_REG_NAME }, { .name = "-num", .value = CFG_ADD_REG_ARCH_NUM }, { .name = "-core", .value = CFG_ADD_REG_IS_CORE }, @@ -662,8 +662,8 @@ void free_reg_desc(struct arc_reg_desc *r) static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { - Jim_GetOptInfo goi; - JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + struct jim_getopt_info goi; + JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); struct arc_reg_desc *reg = calloc(1, sizeof(*reg)); if (!reg) { @@ -692,10 +692,10 @@ static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) /* Parse options. */ while (goi.argc > 0) { - Jim_Nvp *n; - e = Jim_GetOpt_Nvp(&goi, opts_nvp_add_reg, &n); + struct jim_nvp *n; + e = jim_getopt_nvp(&goi, opts_nvp_add_reg, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(&goi, opts_nvp_add_reg, 0); + jim_getopt_nvp_unknown(&goi, opts_nvp_add_reg, 0); free_reg_desc(reg); return e; } @@ -732,7 +732,7 @@ static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) return JIM_ERR; } - e = Jim_GetOpt_Wide(&goi, &archnum); + e = jim_getopt_wide(&goi, &archnum); if (e != JIM_OK) { free_reg_desc(reg); return e; @@ -845,12 +845,12 @@ COMMAND_HANDLER(arc_set_reg_exists) * Reads struct type register field */ static int jim_arc_get_reg_field(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { - Jim_GetOptInfo goi; + struct jim_getopt_info goi; const char *reg_name, *field_name; uint32_t value; int retval; - JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + JIM_CHECK_RETVAL(jim_getopt_setup(&goi, interp, argc-1, argv+1)); LOG_DEBUG("Reading register field"); if (goi.argc != 2) { @@ -863,8 +863,8 @@ static int jim_arc_get_reg_field(Jim_Interp *interp, int argc, Jim_Obj * const * return ERROR_COMMAND_SYNTAX_ERROR; } - JIM_CHECK_RETVAL(Jim_GetOpt_String(&goi, ®_name, NULL)); - JIM_CHECK_RETVAL(Jim_GetOpt_String(&goi, &field_name, NULL)); + JIM_CHECK_RETVAL(jim_getopt_string(&goi, ®_name, NULL)); + JIM_CHECK_RETVAL(jim_getopt_string(&goi, &field_name, NULL)); assert(reg_name); assert(field_name); @@ -932,8 +932,8 @@ COMMAND_HANDLER(arc_l2_cache_disable_auto_cmd) static int jim_handle_actionpoints_num(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); LOG_DEBUG("-"); diff --git a/src/target/arm11.c b/src/target/arm11.c index 68d4e18..ff125d0 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -355,8 +355,7 @@ static int arm11_arch_state(struct target *target) /* REVISIT also display ARM11-specific MMU and cache status ... */ if (target->debug_reason == DBG_REASON_WATCHPOINT) - LOG_USER("Watchpoint triggered at PC %#08x", - (unsigned) arm11->dpm.wp_pc); + LOG_USER("Watchpoint triggered at PC " TARGET_ADDR_FMT, arm11->dpm.wp_addr); return retval; } diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 8f5ad59..35d686e 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -32,7 +32,7 @@ * This file implements support for the ARM Debug Interface version 5 (ADIv5) * debugging architecture. Compared with previous versions, this includes * a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message - * transport, and focusses on memory mapped resources as defined by the + * transport, and focuses on memory mapped resources as defined by the * CoreSight architecture. * * A key concept in ADIv5 is the Debug Access Port, or DAP. A DAP has two @@ -1500,7 +1500,7 @@ enum adiv5_cfg_param { CFG_CTIBASE, /* DEPRECATED */ }; -static const Jim_Nvp nvp_config_opts[] = { +static const struct jim_nvp nvp_config_opts[] = { { .name = "-dap", .value = CFG_DAP }, { .name = "-ap-num", .value = CFG_AP_NUM }, { .name = "-baseaddr", .value = CFG_BASEADDR }, @@ -1508,7 +1508,7 @@ static const Jim_Nvp nvp_config_opts[] = { { .name = NULL, .value = -1 } }; -static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi, +static int adiv5_jim_spot_configure(struct jim_getopt_info *goi, struct adiv5_dap **dap_p, int *ap_num_p, uint32_t *base_p) { if (!goi->argc) @@ -1516,8 +1516,8 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi, Jim_SetEmptyResult(goi->interp); - Jim_Nvp *n; - int e = Jim_Nvp_name2value_obj(goi->interp, nvp_config_opts, + struct jim_nvp *n; + int e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts, goi->argv[0], &n); if (e != JIM_OK) return JIM_CONTINUE; @@ -1526,7 +1526,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi, if (!base_p && (n->value == CFG_BASEADDR || n->value == CFG_CTIBASE)) return JIM_CONTINUE; - e = Jim_GetOpt_Obj(goi, NULL); + e = jim_getopt_obj(goi, NULL); if (e != JIM_OK) return e; @@ -1535,7 +1535,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi, if (goi->isconfigure) { Jim_Obj *o_t; struct adiv5_dap *dap; - e = Jim_GetOpt_Obj(goi, &o_t); + e = jim_getopt_obj(goi, &o_t); if (e != JIM_OK) return e; dap = dap_instance_by_jim_obj(goi->interp, o_t); @@ -1563,7 +1563,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi, case CFG_AP_NUM: if (goi->isconfigure) { jim_wide ap_num; - e = Jim_GetOpt_Wide(goi, &ap_num); + e = jim_getopt_wide(goi, &ap_num); if (e != JIM_OK) return e; if (ap_num < 0 || ap_num > DP_APSEL_MAX) { @@ -1588,7 +1588,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi, case CFG_BASEADDR: if (goi->isconfigure) { jim_wide base; - e = Jim_GetOpt_Wide(goi, &base); + e = jim_getopt_wide(goi, &base); if (e != JIM_OK) return e; *base_p = (uint32_t)base; @@ -1607,7 +1607,7 @@ err_no_param: return JIM_ERR; } -int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi) +int adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi) { struct adiv5_private_config *pc; int e; @@ -1651,7 +1651,7 @@ int adiv5_verify_config(struct adiv5_private_config *pc) } int adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg, - Jim_GetOptInfo *goi) + struct jim_getopt_info *goi) { return adiv5_jim_spot_configure(goi, &cfg->dap, &cfg->ap_num, &cfg->base); } diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 00e4ea2..ce9155a 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -602,7 +602,7 @@ struct adiv5_private_config { }; extern int adiv5_verify_config(struct adiv5_private_config *pc); -extern int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi); +extern int adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi); struct adiv5_mem_ap_spot { struct adiv5_dap *dap; @@ -612,6 +612,6 @@ struct adiv5_mem_ap_spot { extern int adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p); extern int adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg, - Jim_GetOptInfo *goi); + struct jim_getopt_info *goi); #endif /* OPENOCD_TARGET_ARM_ADI_V5_H */ diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index ee9d8aa..30212cb 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -430,7 +430,7 @@ static const struct command_registration cti_instance_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -static int cti_configure(Jim_GetOptInfo *goi, struct arm_cti *cti) +static int cti_configure(struct jim_getopt_info *goi, struct arm_cti *cti) { /* parse config or cget options ... */ while (goi->argc > 0) { @@ -446,7 +446,7 @@ static int cti_configure(Jim_GetOptInfo *goi, struct arm_cti *cti) return JIM_OK; } -static int cti_create(Jim_GetOptInfo *goi) +static int cti_create(struct jim_getopt_info *goi) { struct command_context *cmd_ctx; static struct arm_cti *cti; @@ -463,7 +463,7 @@ static int cti_create(Jim_GetOptInfo *goi) return JIM_ERR; } /* COMMAND */ - Jim_GetOpt_Obj(goi, &new_cmd); + jim_getopt_obj(goi, &new_cmd); /* does this command exist? */ cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG); if (cmd) { @@ -518,8 +518,8 @@ static int cti_create(Jim_GetOptInfo *goi) static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 2) { Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, "<name> [<cti_options> ...]"); diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index a9277e7..747733d 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -156,31 +156,31 @@ enum dap_cfg_param { CFG_IGNORE_SYSPWRUPACK, }; -static const Jim_Nvp nvp_config_opts[] = { +static const struct jim_nvp nvp_config_opts[] = { { .name = "-chain-position", .value = CFG_CHAIN_POSITION }, { .name = "-ignore-syspwrupack", .value = CFG_IGNORE_SYSPWRUPACK }, { .name = NULL, .value = -1 } }; -static int dap_configure(Jim_GetOptInfo *goi, struct arm_dap_object *dap) +static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap) { struct jtag_tap *tap = NULL; - Jim_Nvp *n; + struct jim_nvp *n; int e; /* parse config or cget options ... */ while (goi->argc > 0) { Jim_SetEmptyResult(goi->interp); - e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n); + e = jim_getopt_nvp(goi, nvp_config_opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0); + jim_getopt_nvp_unknown(goi, nvp_config_opts, 0); return e; } switch (n->value) { case CFG_CHAIN_POSITION: { Jim_Obj *o_t; - e = Jim_GetOpt_Obj(goi, &o_t); + e = jim_getopt_obj(goi, &o_t); if (e != JIM_OK) return e; tap = jtag_tap_by_jim_obj(goi->interp, o_t); @@ -210,7 +210,7 @@ static int dap_configure(Jim_GetOptInfo *goi, struct arm_dap_object *dap) return JIM_OK; } -static int dap_create(Jim_GetOptInfo *goi) +static int dap_create(struct jim_getopt_info *goi) { struct command_context *cmd_ctx; static struct arm_dap_object *dap; @@ -227,7 +227,7 @@ static int dap_create(Jim_GetOptInfo *goi) return JIM_ERR; } /* COMMAND */ - Jim_GetOpt_Obj(goi, &new_cmd); + jim_getopt_obj(goi, &new_cmd); /* does this command exist? */ cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG); if (cmd) { @@ -276,8 +276,8 @@ static int dap_create(Jim_GetOptInfo *goi) static int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 2) { Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, "<name> [<dap_options> ...]"); diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index 6bfe355..058f0df 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -1010,7 +1010,7 @@ void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr) /* ?? */ break; } - dpm->wp_pc = addr; + dpm->wp_addr = addr; } /*----------------------------------------------------------------------*/ @@ -1088,9 +1088,11 @@ int arm_dpm_setup(struct arm_dpm *dpm) target->type->remove_breakpoint = dpm_remove_breakpoint; } - /* watchpoint setup */ - target->type->add_watchpoint = dpm_add_watchpoint; - target->type->remove_watchpoint = dpm_remove_watchpoint; + /* watchpoint setup -- optional until it works everywhere */ + if (!target->type->add_watchpoint) { + target->type->add_watchpoint = dpm_add_watchpoint; + target->type->remove_watchpoint = dpm_remove_watchpoint; + } /* FIXME add vector catch support */ diff --git a/src/target/arm_dpm.h b/src/target/arm_dpm.h index 8270782..80587f5 100644 --- a/src/target/arm_dpm.h +++ b/src/target/arm_dpm.h @@ -137,8 +137,12 @@ struct arm_dpm { struct dpm_bp *dbp; struct dpm_wp *dwp; - /** Address of the instruction which triggered a watchpoint. */ - target_addr_t wp_pc; + /** + * Target dependent watchpoint address. + * Either the address of the instruction which triggered a watchpoint + * or the memory address whose access triggered a watchpoint. + */ + target_addr_t wp_addr; /** Recent value of DSCR. */ uint32_t dscr; diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index f935086..6d1e94f 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -73,7 +73,7 @@ enum arm_tpiu_swo_event { TPIU_SWO_EVENT_POST_DISABLE, }; -static const Jim_Nvp nvp_arm_tpiu_swo_event[] = { +static const struct jim_nvp nvp_arm_tpiu_swo_event[] = { { .value = TPIU_SWO_EVENT_PRE_ENABLE, .name = "pre-enable" }, { .value = TPIU_SWO_EVENT_POST_ENABLE, .name = "post-enable" }, { .value = TPIU_SWO_EVENT_PRE_DISABLE, .name = "pre-disable" }, @@ -168,7 +168,7 @@ static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_ LOG_DEBUG("TPIU/SWO: %s event: %s (%d) action : %s", obj->name, - Jim_Nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name, + jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name, event, Jim_GetString(ea->body, NULL)); @@ -185,7 +185,7 @@ static void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_ Jim_MakeErrorMessage(ea->interp); LOG_USER("Error executing event %s on TPIU/SWO %s:\n%s", - Jim_Nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name, + jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name, obj->name, Jim_GetString(Jim_GetResult(ea->interp), NULL)); /* clean both error code and stacktrace before return */ @@ -297,7 +297,7 @@ COMMAND_HANDLER(handle_arm_tpiu_swo_event_list) "----------------------------------------"); for (struct arm_tpiu_swo_event_action *ea = obj->event_action; ea; ea = ea->next) { - Jim_Nvp *opt = Jim_Nvp_value2name_simple(nvp_arm_tpiu_swo_event, ea->event); + struct jim_nvp *opt = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, ea->event); command_print(CMD, "%-25s | %s", opt->name, Jim_GetString(ea->body, NULL)); } @@ -315,7 +315,7 @@ enum arm_tpiu_swo_cfg_param { CFG_EVENT, }; -static const Jim_Nvp nvp_arm_tpiu_swo_config_opts[] = { +static const struct jim_nvp nvp_arm_tpiu_swo_config_opts[] = { { .name = "-port-width", .value = CFG_PORT_WIDTH }, { .name = "-protocol", .value = CFG_PROTOCOL }, { .name = "-formatter", .value = CFG_FORMATTER }, @@ -323,21 +323,21 @@ static const Jim_Nvp nvp_arm_tpiu_swo_config_opts[] = { { .name = "-pin-freq", .value = CFG_BITRATE }, { .name = "-output", .value = CFG_OUTFILE }, { .name = "-event", .value = CFG_EVENT }, - /* handled by mem_ap_spot, added for Jim_GetOpt_NvpUnknown() */ + /* handled by mem_ap_spot, added for jim_getopt_nvp_unknown() */ { .name = "-dap", .value = -1 }, { .name = "-ap-num", .value = -1 }, { .name = "-baseaddr", .value = -1 }, { .name = NULL, .value = -1 }, }; -static const Jim_Nvp nvp_arm_tpiu_swo_protocol_opts[] = { +static const struct jim_nvp nvp_arm_tpiu_swo_protocol_opts[] = { { .name = "sync", .value = TPIU_SPPR_PROTOCOL_SYNC }, { .name = "uart", .value = TPIU_SPPR_PROTOCOL_UART }, { .name = "manchester", .value = TPIU_SPPR_PROTOCOL_MANCHESTER }, { .name = NULL, .value = -1 }, }; -static const Jim_Nvp nvp_arm_tpiu_swo_bool_opts[] = { +static const struct jim_nvp nvp_arm_tpiu_swo_bool_opts[] = { { .name = "on", .value = 1 }, { .name = "yes", .value = 1 }, { .name = "1", .value = 1 }, @@ -349,7 +349,7 @@ static const Jim_Nvp nvp_arm_tpiu_swo_bool_opts[] = { { .name = NULL, .value = -1 }, }; -static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_object *obj) +static int arm_tpiu_swo_configure(struct jim_getopt_info *goi, struct arm_tpiu_swo_object *obj) { assert(obj != NULL); @@ -368,10 +368,10 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec if (e == JIM_ERR) return e; - Jim_Nvp *n; - e = Jim_GetOpt_Nvp(goi, nvp_arm_tpiu_swo_config_opts, &n); + struct jim_nvp *n; + e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_config_opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_arm_tpiu_swo_config_opts, 0); + jim_getopt_nvp_unknown(goi, nvp_arm_tpiu_swo_config_opts, 0); return e; } @@ -379,7 +379,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec case CFG_PORT_WIDTH: if (goi->isconfigure) { jim_wide port_width; - e = Jim_GetOpt_Wide(goi, &port_width); + e = jim_getopt_wide(goi, &port_width); if (e != JIM_OK) return e; if (port_width < 1 || port_width > 32) { @@ -395,16 +395,16 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec break; case CFG_PROTOCOL: if (goi->isconfigure) { - Jim_Nvp *p; - e = Jim_GetOpt_Nvp(goi, nvp_arm_tpiu_swo_protocol_opts, &p); + struct jim_nvp *p; + e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_protocol_opts, &p); if (e != JIM_OK) return e; obj->pin_protocol = p->value; } else { if (goi->argc) goto err_no_params; - Jim_Nvp *p; - e = Jim_Nvp_value2name(goi->interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p); + struct jim_nvp *p; + e = jim_nvp_value2name(goi->interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p); if (e != JIM_OK) { Jim_SetResultString(goi->interp, "protocol error", -1); return JIM_ERR; @@ -414,16 +414,16 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec break; case CFG_FORMATTER: if (goi->isconfigure) { - Jim_Nvp *p; - e = Jim_GetOpt_Nvp(goi, nvp_arm_tpiu_swo_bool_opts, &p); + struct jim_nvp *p; + e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_bool_opts, &p); if (e != JIM_OK) return e; obj->en_formatter = p->value; } else { if (goi->argc) goto err_no_params; - Jim_Nvp *p; - e = Jim_Nvp_value2name(goi->interp, nvp_arm_tpiu_swo_bool_opts, obj->en_formatter, &p); + struct jim_nvp *p; + e = jim_nvp_value2name(goi->interp, nvp_arm_tpiu_swo_bool_opts, obj->en_formatter, &p); if (e != JIM_OK) { Jim_SetResultString(goi->interp, "formatter error", -1); return JIM_ERR; @@ -434,7 +434,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec case CFG_TRACECLKIN: if (goi->isconfigure) { jim_wide clk; - e = Jim_GetOpt_Wide(goi, &clk); + e = jim_getopt_wide(goi, &clk); if (e != JIM_OK) return e; obj->traceclkin_freq = clk; @@ -447,7 +447,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec case CFG_BITRATE: if (goi->isconfigure) { jim_wide clk; - e = Jim_GetOpt_Wide(goi, &clk); + e = jim_getopt_wide(goi, &clk); if (e != JIM_OK) return e; obj->swo_pin_freq = clk; @@ -460,7 +460,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec case CFG_OUTFILE: if (goi->isconfigure) { const char *s; - e = Jim_GetOpt_String(goi, &s, NULL); + e = jim_getopt_string(goi, &s, NULL); if (e != JIM_OK) return e; if (s[0] == ':') { @@ -498,13 +498,13 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec } { - Jim_Nvp *p; + struct jim_nvp *p; Jim_Obj *o; struct arm_tpiu_swo_event_action *ea = obj->event_action; - e = Jim_GetOpt_Nvp(goi, nvp_arm_tpiu_swo_event, &p); + e = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_event, &p); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_arm_tpiu_swo_event, 1); + jim_getopt_nvp_unknown(goi, nvp_arm_tpiu_swo_event, 1); return e; } @@ -529,7 +529,7 @@ static int arm_tpiu_swo_configure(Jim_GetOptInfo *goi, struct arm_tpiu_swo_objec Jim_DecrRefCount(ea->interp, ea->body); ea->event = p->value; ea->interp = goi->interp; - Jim_GetOpt_Obj(goi, &o); + jim_getopt_obj(goi, &o); ea->body = Jim_DuplicateObj(goi->interp, o); Jim_IncrRefCount(ea->body); } else { @@ -551,9 +551,9 @@ err_no_params: static int jim_arm_tpiu_swo_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { struct command *c = jim_to_command(interp); - Jim_GetOptInfo goi; + struct jim_getopt_info goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); goi.isconfigure = !strcmp(c->name, "configure"); if (goi.argc < 1) { Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, @@ -670,8 +670,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const value = 0; } if (!value) { - Jim_Nvp *p; - Jim_Nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p); + 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; } @@ -897,8 +897,8 @@ static int arm_tpiu_swo_create(Jim_Interp *interp, struct arm_tpiu_swo_object *o static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 1) { Jim_WrongNumArgs(goi.interp, 1, goi.argv, "?name? ..options..."); return JIM_ERR; @@ -915,7 +915,7 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const obj->port_width = 1; Jim_Obj *n; - Jim_GetOpt_Obj(&goi, &n); + jim_getopt_obj(&goi, &n); obj->name = strdup(Jim_GetString(n, NULL)); if (!obj->name) { LOG_ERROR("Out of memory"); diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index b725853..8ba9136 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1149,7 +1149,7 @@ static const struct command_registration arm_exec_command_handlers[] = { .handler = handle_arm_disassemble_command, .mode = COMMAND_EXEC, .usage = "address [count ['thumb']]", - .help = "disassemble instructions ", + .help = "disassemble instructions", }, { .name = "mcr", diff --git a/src/target/armv7a.c b/src/target/armv7a.c index abca335..5f7b008 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -570,9 +570,6 @@ int armv7a_arch_state(struct target *target) if (arm->core_mode == ARM_MODE_ABT) armv7a_show_fault_registers(target); - if (target->debug_reason == DBG_REASON_WATCHPOINT) - LOG_USER("Watchpoint triggered at PC %#08x", - (unsigned) armv7a->dpm.wp_pc); return ERROR_OK; } diff --git a/src/target/armv7a_cache_l2x.c b/src/target/armv7a_cache_l2x.c index 3607a51..8ecdb00 100644 --- a/src/target/armv7a_cache_l2x.c +++ b/src/target/armv7a_cache_l2x.c @@ -325,7 +325,7 @@ static const struct command_registration arm7a_l2x_cache_commands[] = { .name = "conf", .handler = armv7a_l2x_cache_conf_cmd, .mode = COMMAND_ANY, - .help = "configure l2x cache ", + .help = "configure l2x cache", .usage = "<base_addr> <number_of_way>", }, { diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 101094a..11770b5 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -125,6 +125,29 @@ static const struct { { ARMV7M_FAULTMASK, "faultmask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, { ARMV7M_CONTROL, "control", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + /* ARMv8-M specific registers */ + { ARMV8M_MSP_NS, "msp_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" }, + { ARMV8M_PSP_NS, "psp_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" }, + { ARMV8M_MSP_S, "msp_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" }, + { ARMV8M_PSP_S, "psp_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" }, + { ARMV8M_MSPLIM_S, "msplim_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" }, + { ARMV8M_PSPLIM_S, "psplim_s", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" }, + { ARMV8M_MSPLIM_NS, "msplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" }, + { ARMV8M_PSPLIM_NS, "psplim_ns", 32, REG_TYPE_DATA_PTR, "stack", "v8-m.sp" }, + + { ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S, "pmsk_bpri_fltmsk_ctrl_s", 32, REG_TYPE_INT, NULL, NULL }, + { ARMV8M_PRIMASK_S, "primask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + { ARMV8M_BASEPRI_S, "basepri_s", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + { ARMV8M_FAULTMASK_S, "faultmask_s", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + { ARMV8M_CONTROL_S, "control_s", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + + { ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS, "pmsk_bpri_fltmsk_ctrl_ns", 32, REG_TYPE_INT, NULL, NULL }, + { ARMV8M_PRIMASK_NS, "primask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + { ARMV8M_BASEPRI_NS, "basepri_ns", 8, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + { ARMV8M_FAULTMASK_NS, "faultmask_ns", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + { ARMV8M_CONTROL_NS, "control_ns", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system" }, + + /* FPU registers */ { ARMV7M_D0, "d0", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, { ARMV7M_D1, "d1", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, { ARMV7M_D2, "d2", 64, REG_TYPE_IEEE_DOUBLE, "float", "org.gnu.gdb.arm.vfp" }, @@ -243,6 +266,15 @@ static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) case ARMV7M_PMSK_BPRI_FLTMSK_CTRL: return ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL; + case ARMV8M_MSP_NS...ARMV8M_PSPLIM_NS: + return arm_reg_id - ARMV8M_MSP_NS + ARMV8M_REGSEL_MSP_NS; + + case ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S: + return ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S; + + case ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS: + return ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_NS; + case ARMV7M_FPSCR: return ARMV7M_REGSEL_FPSCR; @@ -258,28 +290,26 @@ static uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id) static bool armv7m_map_reg_packing(unsigned int arm_reg_id, unsigned int *reg32_id, uint32_t *offset) { + switch (arm_reg_id) { - case ARMV7M_PRIMASK: + case ARMV7M_PRIMASK...ARMV7M_CONTROL: *reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL; - *offset = 0; + *offset = arm_reg_id - ARMV7M_PRIMASK; return true; - case ARMV7M_BASEPRI: - *reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL; - *offset = 1; + case ARMV8M_PRIMASK_S...ARMV8M_CONTROL_S: + *reg32_id = ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S; + *offset = arm_reg_id - ARMV8M_PRIMASK_S; return true; - case ARMV7M_FAULTMASK: - *reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL; - *offset = 2; - return true; - case ARMV7M_CONTROL: - *reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL; - *offset = 3; + case ARMV8M_PRIMASK_NS...ARMV8M_CONTROL_NS: + *reg32_id = ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS; + *offset = arm_reg_id - ARMV8M_PRIMASK_NS; return true; default: return false; } + } static int armv7m_read_core_reg(struct target *target, struct reg *r, @@ -299,11 +329,17 @@ static int armv7m_read_core_reg(struct target *target, struct reg *r, if (r->size <= 8) { /* any 8-bit or shorter register is packed */ - uint32_t offset = 0; /* silence false gcc warning */ + uint32_t offset; unsigned int reg32_id; bool is_packed = armv7m_map_reg_packing(num, ®32_id, &offset); - assert(is_packed); + if (!is_packed) { + /* We should not get here as all 8-bit or shorter registers + * are packed */ + assert(false); + /* assert() does nothing if NDEBUG is defined */ + return ERROR_FAIL; + } struct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id]; /* Read 32-bit container register if not cached */ @@ -364,11 +400,17 @@ static int armv7m_write_core_reg(struct target *target, struct reg *r, if (r->size <= 8) { /* any 8-bit or shorter register is packed */ - uint32_t offset = 0; /* silence false gcc warning */ + uint32_t offset; unsigned int reg32_id; bool is_packed = armv7m_map_reg_packing(num, ®32_id, &offset); - assert(is_packed); + if (!is_packed) { + /* We should not get here as all 8-bit or shorter registers + * are packed */ + assert(false); + /* assert() does nothing if NDEBUG is defined */ + return ERROR_FAIL; + } struct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id]; if (!r32->valid) { @@ -743,7 +785,8 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) reg_list[i].value = arch_info[i].value; reg_list[i].dirty = false; reg_list[i].valid = false; - reg_list[i].hidden = i == ARMV7M_PMSK_BPRI_FLTMSK_CTRL; + reg_list[i].hidden = (i == ARMV7M_PMSK_BPRI_FLTMSK_CTRL || + i == ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS || i == ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S); reg_list[i].type = &armv7m_reg_type; reg_list[i].arch_info = &arch_info[i]; diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 652dbe7..f3445e1 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -60,7 +60,18 @@ enum { ARMV7M_REGSEL_MSP, ARMV7M_REGSEL_PSP, + ARMV8M_REGSEL_MSP_NS = 0x18, + ARMV8M_REGSEL_PSP_NS, + ARMV8M_REGSEL_MSP_S, + ARMV8M_REGSEL_PSP_S, + ARMV8M_REGSEL_MSPLIM_S, + ARMV8M_REGSEL_PSPLIM_S, + ARMV8M_REGSEL_MSPLIM_NS, + ARMV8M_REGSEL_PSPLIM_NS, + ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL = 0x14, + ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S = 0x22, + ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_NS = 0x23, ARMV7M_REGSEL_FPSCR = 0x21, /* 32bit Floating-point registers */ @@ -129,6 +140,8 @@ enum { /* following indices are arbitrary, do not match DCRSR.REGSEL selectors */ + /* A block of container and contained registers follows: + * THE ORDER IS IMPORTANT to the end of the block ! */ /* working register for packing/unpacking special regs, hidden from gdb */ ARMV7M_PMSK_BPRI_FLTMSK_CTRL, @@ -142,6 +155,35 @@ enum { ARMV7M_BASEPRI, ARMV7M_FAULTMASK, ARMV7M_CONTROL, + /* The end of block of container and contained registers */ + + /* ARMv8-M specific registers */ + ARMV8M_MSP_NS, + ARMV8M_PSP_NS, + ARMV8M_MSP_S, + ARMV8M_PSP_S, + ARMV8M_MSPLIM_S, + ARMV8M_PSPLIM_S, + ARMV8M_MSPLIM_NS, + ARMV8M_PSPLIM_NS, + + /* A block of container and contained registers follows: + * THE ORDER IS IMPORTANT to the end of the block ! */ + ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S, + ARMV8M_PRIMASK_S, + ARMV8M_BASEPRI_S, + ARMV8M_FAULTMASK_S, + ARMV8M_CONTROL_S, + /* The end of block of container and contained registers */ + + /* A block of container and contained registers follows: + * THE ORDER IS IMPORTANT to the end of the block ! */ + ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS, + ARMV8M_PRIMASK_NS, + ARMV8M_BASEPRI_NS, + ARMV8M_FAULTMASK_NS, + ARMV8M_CONTROL_NS, + /* The end of block of container and contained registers */ /* 64bit Floating-point registers */ ARMV7M_D0, @@ -170,6 +212,8 @@ enum { ARMV7M_CORE_LAST_REG = ARMV7M_xPSR, ARMV7M_FPU_FIRST_REG = ARMV7M_D0, ARMV7M_FPU_LAST_REG = ARMV7M_FPSCR, + ARMV8M_FIRST_REG = ARMV8M_MSP_NS, + ARMV8M_LAST_REG = ARMV8M_CONTROL_NS, }; enum { @@ -184,7 +228,7 @@ enum { #define ARMV7M_COMMON_MAGIC 0x2A452A45 struct armv7m_common { - struct arm arm; + struct arm arm; int common_magic; int exception_number; diff --git a/src/target/armv8.c b/src/target/armv8.c index 6bf3b11..6d60a1c 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -1025,7 +1025,7 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command) unsigned int argp = 0; int retval; - static const Jim_Nvp nvp_ecatch_modes[] = { + static const struct jim_nvp nvp_ecatch_modes[] = { { .name = "off", .value = 0 }, { .name = "nsec_el1", .value = (1 << 5) }, { .name = "nsec_el2", .value = (2 << 5) }, @@ -1035,7 +1035,7 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command) { .name = "sec_el13", .value = (5 << 1) }, { .name = NULL, .value = -1 }, }; - const Jim_Nvp *n; + const struct jim_nvp *n; if (CMD_ARGC == 0) { const char *sec = NULL, *nsec = NULL; @@ -1045,11 +1045,11 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command) if (retval != ERROR_OK) return retval; - n = Jim_Nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0x0f); + n = jim_nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0x0f); if (n->name != NULL) sec = n->name; - n = Jim_Nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0xf0); + n = jim_nvp_value2name_simple(nvp_ecatch_modes, edeccr & 0xf0); if (n->name != NULL) nsec = n->name; @@ -1063,7 +1063,7 @@ COMMAND_HANDLER(armv8_handle_exception_catch_command) } while (CMD_ARGC > argp) { - n = Jim_Nvp_name2value_simple(nvp_ecatch_modes, CMD_ARGV[argp]); + n = jim_nvp_name2value_simple(nvp_ecatch_modes, CMD_ARGV[argp]); if (n->name == NULL) { LOG_ERROR("Unknown option: %s", CMD_ARGV[argp]); return ERROR_FAIL; @@ -1169,8 +1169,7 @@ int armv8_arch_state(struct target *target) armv8_show_fault_registers(target); if (target->debug_reason == DBG_REASON_WATCHPOINT) - LOG_USER("Watchpoint triggered at PC %#08x", - (unsigned) armv8->dpm.wp_pc); + LOG_USER("Watchpoint triggered at " TARGET_ADDR_FMT, armv8->dpm.wp_addr); return ERROR_OK; } diff --git a/src/target/armv8.h b/src/target/armv8.h index 978b2ad..f09f3ab 100644 --- a/src/target/armv8.h +++ b/src/target/armv8.h @@ -257,8 +257,8 @@ static inline bool is_armv8(struct armv8_common *armv8) #define CPUV8_DBG_EDESR 0x20 #define CPUV8_DBG_EDECR 0x24 -#define CPUV8_DBG_WFAR0 0x30 -#define CPUV8_DBG_WFAR1 0x34 +#define CPUV8_DBG_EDWAR0 0x30 +#define CPUV8_DBG_EDWAR1 0x34 #define CPUV8_DBG_DSCR 0x088 #define CPUV8_DBG_DRCR 0x090 #define CPUV8_DBG_ECCR 0x098 diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index e7d0f86..6ef8c33 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -1279,27 +1279,6 @@ static int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp) return retval; } -void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t addr) -{ - switch (dpm->arm->core_state) { - case ARM_STATE_ARM: - case ARM_STATE_AARCH64: - addr -= 8; - break; - case ARM_STATE_THUMB: - case ARM_STATE_THUMB_EE: - addr -= 4; - break; - case ARM_STATE_JAZELLE: - /* ?? */ - break; - default: - LOG_DEBUG("Unknown core_state"); - break; - } - dpm->wp_pc = addr; -} - /* * Handle exceptions taken in debug state. This happens mostly for memory * accesses that violated a MMU policy. Taking an exception while in debug diff --git a/src/target/armv8_dpm.h b/src/target/armv8_dpm.h index a6cade3..c30b04f 100644 --- a/src/target/armv8_dpm.h +++ b/src/target/armv8_dpm.h @@ -38,8 +38,6 @@ int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode); int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp); -void armv8_dpm_report_wfar(struct arm_dpm *dpm, uint64_t wfar); - /* DSCR bits; see ARMv7a arch spec section C10.3.1. * Not all v7 bits are valid in v6. */ diff --git a/src/target/avr32_mem.c b/src/target/avr32_mem.c index 71ec0b4..8f38a18 100644 --- a/src/target/avr32_mem.c +++ b/src/target/avr32_mem.c @@ -176,7 +176,7 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, */ if (addr & 3) { /* - * mwa_read will read whole world, no nead to fiddle + * mwa_read will read whole world, no need to fiddle * with address. It will be truncated in set_addr */ retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, @@ -248,7 +248,7 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, */ if (addr & 3) { /* - * mwa_read will read whole world, no nead to fiddle + * mwa_read will read whole world, no need to fiddle * with address. It will be truncated in set_addr */ retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 5018a91..6b76656 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -23,6 +23,9 @@ * Copyright (C) 2013 Kamal Dasu * * kdasu.kdev@gmail.com * * * + * Copyright (C) 2016 Chengyu Zheng * + * chengyu.zheng@polimi.it : watchpoint support * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -58,6 +61,7 @@ #include "jtag/interface.h" #include "transport/transport.h" #include "smp.h" +#include <helper/bits.h> #include <helper/time_support.h> static int cortex_a_poll(struct target *target); @@ -80,6 +84,16 @@ static int cortex_a_virt2phys(struct target *target, static int cortex_a_read_cpu_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); +static unsigned int ilog2(unsigned int x) +{ + unsigned int y = 0; + x /= 2; + while (x) { + ++y; + x /= 2; + } + return y; +} /* restore cp15_control_reg at resume */ static int cortex_a_restore_cp15_control_reg(struct target *target) @@ -1658,6 +1672,200 @@ static int cortex_a_remove_breakpoint(struct target *target, struct breakpoint * return ERROR_OK; } +/** + * Sets a watchpoint for an Cortex-A target in one of the watchpoint units. It is + * considered a bug to call this function when there are no available watchpoint + * units. + * + * @param target Pointer to an Cortex-A target to set a watchpoint on + * @param watchpoint Pointer to the watchpoint to be set + * @return Error status if watchpoint set fails or the result of executing the + * JTAG queue + */ +static int cortex_a_set_watchpoint(struct target *target, struct watchpoint *watchpoint) +{ + int retval = ERROR_OK; + int wrp_i = 0; + uint32_t control; + uint32_t address; + uint8_t address_mask; + uint8_t byte_address_select; + uint8_t load_store_access_control = 0x3; + struct cortex_a_common *cortex_a = target_to_cortex_a(target); + struct armv7a_common *armv7a = &cortex_a->armv7a_common; + struct cortex_a_wrp *wrp_list = cortex_a->wrp_list; + + if (watchpoint->set) { + LOG_WARNING("watchpoint already set"); + return retval; + } + + /* check available context WRPs */ + while (wrp_list[wrp_i].used && (wrp_i < cortex_a->wrp_num)) + wrp_i++; + + if (wrp_i >= cortex_a->wrp_num) { + LOG_ERROR("ERROR Can not find free Watchpoint Register Pair"); + return ERROR_FAIL; + } + + if (watchpoint->length == 0 || watchpoint->length > 0x80000000U || + (watchpoint->length & (watchpoint->length - 1))) { + LOG_WARNING("watchpoint length must be a power of 2"); + return ERROR_FAIL; + } + + if (watchpoint->address & (watchpoint->length - 1)) { + LOG_WARNING("watchpoint address must be aligned at length"); + return ERROR_FAIL; + } + + /* FIXME: ARM DDI 0406C: address_mask is optional. What to do if it's missing? */ + /* handle wp length 1 and 2 through byte select */ + switch (watchpoint->length) { + case 1: + byte_address_select = BIT(watchpoint->address & 0x3); + address = watchpoint->address & ~0x3; + address_mask = 0; + break; + + case 2: + byte_address_select = 0x03 << (watchpoint->address & 0x2); + address = watchpoint->address & ~0x3; + address_mask = 0; + break; + + case 4: + byte_address_select = 0x0f; + address = watchpoint->address; + address_mask = 0; + break; + + default: + byte_address_select = 0xff; + address = watchpoint->address; + address_mask = ilog2(watchpoint->length); + break; + } + + watchpoint->set = wrp_i + 1; + control = (address_mask << 24) | + (byte_address_select << 5) | + (load_store_access_control << 3) | + (0x3 << 1) | 1; + wrp_list[wrp_i].used = 1; + wrp_list[wrp_i].value = address; + wrp_list[wrp_i].control = control; + + retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base + + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].WRPn, + wrp_list[wrp_i].value); + if (retval != ERROR_OK) + return retval; + + retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base + + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].WRPn, + wrp_list[wrp_i].control); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("wp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, wrp_i, + wrp_list[wrp_i].control, + wrp_list[wrp_i].value); + + return ERROR_OK; +} + +/** + * Unset an existing watchpoint and clear the used watchpoint unit. + * + * @param target Pointer to the target to have the watchpoint removed + * @param watchpoint Pointer to the watchpoint to be removed + * @return Error status while trying to unset the watchpoint or the result of + * executing the JTAG queue + */ +static int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *watchpoint) +{ + int retval; + struct cortex_a_common *cortex_a = target_to_cortex_a(target); + struct armv7a_common *armv7a = &cortex_a->armv7a_common; + struct cortex_a_wrp *wrp_list = cortex_a->wrp_list; + + if (!watchpoint->set) { + LOG_WARNING("watchpoint not set"); + return ERROR_OK; + } + + int wrp_i = watchpoint->set - 1; + if (wrp_i < 0 || wrp_i >= cortex_a->wrp_num) { + LOG_DEBUG("Invalid WRP number in watchpoint"); + return ERROR_OK; + } + LOG_DEBUG("wrp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, wrp_i, + wrp_list[wrp_i].control, wrp_list[wrp_i].value); + wrp_list[wrp_i].used = 0; + wrp_list[wrp_i].value = 0; + wrp_list[wrp_i].control = 0; + retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base + + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].WRPn, + wrp_list[wrp_i].control); + if (retval != ERROR_OK) + return retval; + retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base + + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].WRPn, + wrp_list[wrp_i].value); + if (retval != ERROR_OK) + return retval; + watchpoint->set = 0; + + return ERROR_OK; +} + +/** + * Add a watchpoint to an Cortex-A target. If there are no watchpoint units + * available, an error response is returned. + * + * @param target Pointer to the Cortex-A target to add a watchpoint to + * @param watchpoint Pointer to the watchpoint to be added + * @return Error status while trying to add the watchpoint + */ +static int cortex_a_add_watchpoint(struct target *target, struct watchpoint *watchpoint) +{ + struct cortex_a_common *cortex_a = target_to_cortex_a(target); + + if (cortex_a->wrp_num_available < 1) { + LOG_INFO("no hardware watchpoint available"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + int retval = cortex_a_set_watchpoint(target, watchpoint); + if (retval != ERROR_OK) + return retval; + + cortex_a->wrp_num_available--; + return ERROR_OK; +} + +/** + * Remove a watchpoint from an Cortex-A target. The watchpoint will be unset and + * the used watchpoint unit will be reopened. + * + * @param target Pointer to the target to remove a watchpoint from + * @param watchpoint Pointer to the watchpoint to be removed + * @return Result of trying to unset the watchpoint + */ +static int cortex_a_remove_watchpoint(struct target *target, struct watchpoint *watchpoint) +{ + struct cortex_a_common *cortex_a = target_to_cortex_a(target); + + if (watchpoint->set) { + cortex_a->wrp_num_available++; + cortex_a_unset_watchpoint(target, watchpoint); + } + return ERROR_OK; +} + + /* * Cortex-A Reset functions */ @@ -2837,6 +3045,20 @@ static int cortex_a_examine_first(struct target *target) LOG_DEBUG("Configured %i hw breakpoints", cortex_a->brp_num); + /* Setup Watchpoint Register Pairs */ + cortex_a->wrp_num = ((didr >> 28) & 0x0F) + 1; + cortex_a->wrp_num_available = cortex_a->wrp_num; + free(cortex_a->wrp_list); + cortex_a->wrp_list = calloc(cortex_a->wrp_num, sizeof(struct cortex_a_wrp)); + for (i = 0; i < cortex_a->wrp_num; i++) { + cortex_a->wrp_list[i].used = 0; + cortex_a->wrp_list[i].value = 0; + cortex_a->wrp_list[i].control = 0; + cortex_a->wrp_list[i].WRPn = i; + } + + LOG_DEBUG("Configured %i hw watchpoints", cortex_a->wrp_num); + /* select debug_ap as default */ swjdp->apsel = armv7a->debug_ap->ap_num; @@ -2959,6 +3181,7 @@ static void cortex_a_deinit_target(struct target *target) dscr & ~DSCR_HALT_DBG_MODE); } + free(cortex_a->wrp_list); free(cortex_a->brp_list); arm_free_reg_cache(dpm->arm); free(dpm->dbp); @@ -3036,15 +3259,15 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command) struct target *target = get_current_target(CMD_CTX); struct cortex_a_common *cortex_a = target_to_cortex_a(target); - static const Jim_Nvp nvp_maskisr_modes[] = { + static const struct jim_nvp nvp_maskisr_modes[] = { { .name = "off", .value = CORTEX_A_ISRMASK_OFF }, { .name = "on", .value = CORTEX_A_ISRMASK_ON }, { .name = NULL, .value = -1 }, }; - const Jim_Nvp *n; + const struct jim_nvp *n; if (CMD_ARGC > 0) { - n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]); + n = jim_nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]); if (n->name == NULL) { LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]); return ERROR_COMMAND_SYNTAX_ERROR; @@ -3053,7 +3276,7 @@ COMMAND_HANDLER(handle_cortex_a_mask_interrupts_command) cortex_a->isrmasking_mode = n->value; } - n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode); + n = jim_nvp_value2name_simple(nvp_maskisr_modes, cortex_a->isrmasking_mode); command_print(CMD, "cortex_a interrupt mask %s", n->name); return ERROR_OK; @@ -3064,22 +3287,22 @@ COMMAND_HANDLER(handle_cortex_a_dacrfixup_command) struct target *target = get_current_target(CMD_CTX); struct cortex_a_common *cortex_a = target_to_cortex_a(target); - static const Jim_Nvp nvp_dacrfixup_modes[] = { + static const struct jim_nvp nvp_dacrfixup_modes[] = { { .name = "off", .value = CORTEX_A_DACRFIXUP_OFF }, { .name = "on", .value = CORTEX_A_DACRFIXUP_ON }, { .name = NULL, .value = -1 }, }; - const Jim_Nvp *n; + const struct jim_nvp *n; if (CMD_ARGC > 0) { - n = Jim_Nvp_name2value_simple(nvp_dacrfixup_modes, CMD_ARGV[0]); + n = jim_nvp_name2value_simple(nvp_dacrfixup_modes, CMD_ARGV[0]); if (n->name == NULL) return ERROR_COMMAND_SYNTAX_ERROR; cortex_a->dacrfixup_mode = n->value; } - n = Jim_Nvp_value2name_simple(nvp_dacrfixup_modes, cortex_a->dacrfixup_mode); + n = jim_nvp_value2name_simple(nvp_dacrfixup_modes, cortex_a->dacrfixup_mode); command_print(CMD, "cortex_a domain access control fixup %s", n->name); return ERROR_OK; @@ -3173,8 +3396,8 @@ struct target_type cortexa_target = { .add_context_breakpoint = cortex_a_add_context_breakpoint, .add_hybrid_breakpoint = cortex_a_add_hybrid_breakpoint, .remove_breakpoint = cortex_a_remove_breakpoint, - .add_watchpoint = NULL, - .remove_watchpoint = NULL, + .add_watchpoint = cortex_a_add_watchpoint, + .remove_watchpoint = cortex_a_remove_watchpoint, .commands = cortex_a_command_handlers, .target_create = cortex_a_target_create, @@ -3250,8 +3473,8 @@ struct target_type cortexr4_target = { .add_context_breakpoint = cortex_a_add_context_breakpoint, .add_hybrid_breakpoint = cortex_a_add_hybrid_breakpoint, .remove_breakpoint = cortex_a_remove_breakpoint, - .add_watchpoint = NULL, - .remove_watchpoint = NULL, + .add_watchpoint = cortex_a_add_watchpoint, + .remove_watchpoint = cortex_a_remove_watchpoint, .commands = cortex_r4_command_handlers, .target_create = cortex_r4_target_create, diff --git a/src/target/cortex_a.h b/src/target/cortex_a.h index 197a599..dd135ec 100644 --- a/src/target/cortex_a.h +++ b/src/target/cortex_a.h @@ -71,6 +71,13 @@ struct cortex_a_brp { uint8_t BRPn; }; +struct cortex_a_wrp { + int used; + uint32_t value; + uint32_t control; + uint8_t WRPn; +}; + struct cortex_a_common { int common_magic; @@ -92,6 +99,9 @@ struct cortex_a_common { int brp_num; int brp_num_available; struct cortex_a_brp *brp_list; + int wrp_num; + int wrp_num_available; + struct cortex_a_wrp *wrp_list; uint32_t cpuid; uint32_t didr; diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 2b38b4a..941fef1 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -285,7 +285,6 @@ static int cortex_m_enable_fpb(struct target *target) static int cortex_m_endreset_event(struct target *target) { - int i; int retval; uint32_t dcb_demcr; struct cortex_m_common *cortex_m = target_to_cm(target); @@ -343,14 +342,14 @@ static int cortex_m_endreset_event(struct target *target) cortex_m->fpb_enabled = true; /* Restore FPB registers */ - for (i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) { + for (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) { retval = target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value); if (retval != ERROR_OK) return retval; } /* Restore DWT registers */ - for (i = 0; i < cortex_m->dwt_num_comp; i++) { + for (unsigned int i = 0; i < cortex_m->dwt_num_comp; i++) { retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 0, dwt_list[i].comp); if (retval != ERROR_OK) @@ -728,6 +727,11 @@ static int cortex_m_soft_reset_halt(struct target *target) * core, not the peripherals */ LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead."); + if (!cortex_m->vectreset_supported) { + LOG_ERROR("VECTRESET is not supported on this Cortex-M core"); + return ERROR_FAIL; + } + /* Set C_DEBUGEN */ retval = cortex_m_write_debug_halt_mask(target, 0, C_STEP | C_MASKINTS); if (retval != ERROR_OK) @@ -1266,7 +1270,7 @@ static int cortex_m_deassert_reset(struct target *target) int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint) { int retval; - int fp_num = 0; + unsigned int fp_num = 0; struct cortex_m_common *cortex_m = target_to_cm(target); struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list; @@ -1353,7 +1357,7 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi struct cortex_m_common *cortex_m = target_to_cm(target); struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list; - if (!breakpoint->set) { + if (breakpoint->set <= 0) { LOG_WARNING("breakpoint not set"); return ERROR_OK; } @@ -1366,8 +1370,8 @@ int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoi breakpoint->set); if (breakpoint->type == BKPT_HARD) { - int fp_num = breakpoint->set - 1; - if ((fp_num < 0) || (fp_num >= cortex_m->fp_num_code)) { + unsigned int fp_num = breakpoint->set - 1; + if (fp_num >= cortex_m->fp_num_code) { LOG_DEBUG("Invalid FP Comparator number in breakpoint"); return ERROR_OK; } @@ -1413,7 +1417,7 @@ int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpo static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint) { - int dwt_num = 0; + unsigned int dwt_num = 0; struct cortex_m_common *cortex_m = target_to_cm(target); /* REVISIT Don't fully trust these "not used" records ... users @@ -1498,21 +1502,20 @@ static int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *w { struct cortex_m_common *cortex_m = target_to_cm(target); struct cortex_m_dwt_comparator *comparator; - int dwt_num; - if (!watchpoint->set) { + if (watchpoint->set <= 0) { LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint->unique_id); return ERROR_OK; } - dwt_num = watchpoint->set - 1; + unsigned int dwt_num = watchpoint->set - 1; LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear", watchpoint->unique_id, dwt_num, (unsigned) watchpoint->address); - if ((dwt_num < 0) || (dwt_num >= cortex_m->dwt_num_comp)) { + if (dwt_num >= cortex_m->dwt_num_comp) { LOG_DEBUG("Invalid DWT Comparator number in watchpoint"); return ERROR_OK; } @@ -1851,7 +1854,7 @@ static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target uint32_t dwtcr; struct reg_cache *cache; struct cortex_m_dwt_comparator *comparator; - int reg, i; + int reg; target_read_u32(target, DWT_CTRL, &dwtcr); LOG_DEBUG("DWT_CTRL: 0x%" PRIx32, dwtcr); @@ -1893,7 +1896,7 @@ fail1: dwt_base_regs + reg); comparator = cm->dwt_comparator_list; - for (i = 0; i < cm->dwt_num_comp; i++, comparator++) { + for (unsigned int i = 0; i < cm->dwt_num_comp; i++, comparator++) { int j; comparator->dwt_comparator_address = DWT_COMP0 + 0x10 * i; @@ -1964,7 +1967,6 @@ int cortex_m_examine(struct target *target) { int retval; uint32_t cpuid, fpcr, mvfr0, mvfr1; - int i; struct cortex_m_common *cortex_m = target_to_cm(target); struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap; struct armv7m_common *armv7m = target_to_armv7m(target); @@ -2000,23 +2002,23 @@ int cortex_m_examine(struct target *target) return retval; /* Get CPU Type */ - i = (cpuid >> 4) & 0xf; + unsigned int core = (cpuid >> 4) & 0xf; /* Check if it is an ARMv8-M core */ armv7m->arm.is_armv8m = true; switch (cpuid & ARM_CPUID_PARTNO_MASK) { case CORTEX_M23_PARTNO: - i = 23; + core = 23; break; case CORTEX_M33_PARTNO: - i = 33; + core = 33; break; case CORTEX_M35P_PARTNO: - i = 35; + core = 35; break; case CORTEX_M55_PARTNO: - i = 55; + core = 55; break; default: armv7m->arm.is_armv8m = false; @@ -2025,9 +2027,9 @@ int cortex_m_examine(struct target *target) LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected", - i, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf)); + core, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf)); cortex_m->maskints_erratum = false; - if (i == 7) { + if (core == 7) { uint8_t rev, patch; rev = (cpuid >> 20) & 0xf; patch = (cpuid >> 0) & 0xf; @@ -2038,47 +2040,50 @@ int cortex_m_examine(struct target *target) } LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); - /* VECTRESET is supported only on ARMv7-M cores */ - cortex_m->vectreset_supported = !armv7m->arm.is_armv8m && !armv7m->arm.is_armv6m; - - if (i == 4) { + if (core == 4) { target_read_u32(target, MVFR0, &mvfr0); target_read_u32(target, MVFR1, &mvfr1); /* test for floating point feature on Cortex-M4 */ if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) { - LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i); + LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", core); armv7m->fp_feature = FPV4_SP; } - } else if (i == 7 || i == 33 || i == 35 || i == 55) { + } else if (core == 7 || core == 33 || core == 35 || core == 55) { target_read_u32(target, MVFR0, &mvfr0); target_read_u32(target, MVFR1, &mvfr1); /* test for floating point features on Cortex-M7 */ if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) { - LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", i); + LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", core); armv7m->fp_feature = FPV5_SP; } else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) { - LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", i); + LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", core); armv7m->fp_feature = FPV5_DP; } - } else if (i == 0) { + } else if (core == 0) { /* Cortex-M0 does not support unaligned memory access */ armv7m->arm.is_armv6m = true; } + /* VECTRESET is supported only on ARMv7-M cores */ + cortex_m->vectreset_supported = !armv7m->arm.is_armv8m && !armv7m->arm.is_armv6m; + /* Check for FPU, otherwise mark FPU register as non-existent */ if (armv7m->fp_feature == FP_NONE) for (size_t idx = ARMV7M_FPU_FIRST_REG; idx <= ARMV7M_FPU_LAST_REG; idx++) armv7m->arm.core_cache->reg_list[idx].exist = false; + if (!armv7m->arm.is_armv8m) + for (size_t idx = ARMV8M_FIRST_REG; idx <= ARMV8M_LAST_REG; idx++) + armv7m->arm.core_cache->reg_list[idx].exist = false; if (!armv7m->stlink) { - if (i == 3 || i == 4) + if (core == 3 || core == 4) /* Cortex-M3/M4 have 4096 bytes autoincrement range, * s. ARM IHI 0031C: MEM-AP 7.2.2 */ armv7m->debug_ap->tar_autoincr_block = (1 << 12); - else if (i == 7) + else if (core == 7) /* Cortex-M7 has only 1024 bytes autoincrement range */ armv7m->debug_ap->tar_autoincr_block = (1 << 10); } @@ -2119,7 +2124,7 @@ int cortex_m_examine(struct target *target) cortex_m->fp_num_code + cortex_m->fp_num_lit, sizeof(struct cortex_m_fp_comparator)); cortex_m->fpb_enabled = fpcr & 1; - for (i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) { + for (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) { cortex_m->fp_comparator_list[i].type = (i < cortex_m->fp_num_code) ? FPCR_CODE : FPCR_LITERAL; cortex_m->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i; @@ -2393,14 +2398,14 @@ COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command) struct cortex_m_common *cortex_m = target_to_cm(target); int retval; - static const Jim_Nvp nvp_maskisr_modes[] = { + static const struct jim_nvp nvp_maskisr_modes[] = { { .name = "auto", .value = CORTEX_M_ISRMASK_AUTO }, { .name = "off", .value = CORTEX_M_ISRMASK_OFF }, { .name = "on", .value = CORTEX_M_ISRMASK_ON }, { .name = "steponly", .value = CORTEX_M_ISRMASK_STEPONLY }, { .name = NULL, .value = -1 }, }; - const Jim_Nvp *n; + const struct jim_nvp *n; retval = cortex_m_verify_pointer(CMD, cortex_m); @@ -2413,14 +2418,14 @@ COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command) } if (CMD_ARGC > 0) { - n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]); + n = jim_nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]); if (n->name == NULL) return ERROR_COMMAND_SYNTAX_ERROR; cortex_m->isrmasking_mode = n->value; cortex_m_set_maskints_for_halt(target); } - n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_m->isrmasking_mode); + n = jim_nvp_value2name_simple(nvp_maskisr_modes, cortex_m->isrmasking_mode); command_print(CMD, "cortex_m interrupt mask %s", n->name); return ERROR_OK; diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 1e2197b..0f221ff 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -196,15 +196,15 @@ struct cortex_m_common { uint32_t nvic_icsr; /* Interrupt Control State Register - shows active and pending IRQ */ /* Flash Patch and Breakpoint (FPB) */ - int fp_num_lit; - int fp_num_code; + unsigned int fp_num_lit; + unsigned int fp_num_code; int fp_rev; bool fpb_enabled; struct cortex_m_fp_comparator *fp_comparator_list; /* Data Watchpoint and Trace (DWT) */ - int dwt_num_comp; - int dwt_comp_available; + unsigned int dwt_num_comp; + unsigned int dwt_comp_available; uint32_t dwt_devarch; struct cortex_m_dwt_comparator *dwt_comparator_list; struct reg_cache *dwt_cache; diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c index 864376f..c9e25b3 100644 --- a/src/target/dsp563xx.c +++ b/src/target/dsp563xx.c @@ -2244,7 +2244,7 @@ static const struct command_registration dsp563xx_command_handlers[] = { .handler = dsp563xx_remove_watchpoint_command, .mode = COMMAND_EXEC, .help = "remove watchpoint custom", - .usage = " ", + .usage = "", }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/embeddedice.h b/src/target/embeddedice.h index 4b5c816..4a62cef 100644 --- a/src/target/embeddedice.h +++ b/src/target/embeddedice.h @@ -106,7 +106,7 @@ int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size); int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout); -/* If many embeddedice_write_reg() follow eachother, then the >1 invocations can be +/* If many embeddedice_write_reg() follow each other, then the >1 invocations can be * this faster version of embeddedice_write_reg */ static inline void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg_addr, uint32_t value) diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c index 89c0c02..0c3d7f7 100644 --- a/src/target/mem_ap.c +++ b/src/target/mem_ap.c @@ -18,14 +18,16 @@ #include "target.h" #include "target_type.h" -#include "arm.h" #include "arm_adi_v5.h" #include "register.h" #include <jtag/jtag.h> +#define MEM_AP_COMMON_MAGIC 0x4DE4DA50 + struct mem_ap { - struct arm arm; + int common_magic; + struct adiv5_dap *dap; struct adiv5_ap *ap; int ap_num; }; @@ -51,8 +53,8 @@ static int mem_ap_target_create(struct target *target, Jim_Interp *interp) } mem_ap->ap_num = pc->ap_num; - mem_ap->arm.common_magic = ARM_COMMON_MAGIC; - mem_ap->arm.dap = pc->dap; + mem_ap->common_magic = MEM_AP_COMMON_MAGIC; + mem_ap->dap = pc->dap; target->arch_info = mem_ap; @@ -137,7 +139,7 @@ static int mem_ap_examine(struct target *target) struct mem_ap *mem_ap = target->arch_info; if (!target_was_examined(target)) { - mem_ap->ap = dap_ap(mem_ap->arm.dap, mem_ap->ap_num); + mem_ap->ap = dap_ap(mem_ap->dap, mem_ap->ap_num); target_set_examined(target); target->state = TARGET_UNKNOWN; target->debug_reason = DBG_REASON_UNDEFINED; diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c index 246dbd0..f7647c3 100644 --- a/src/target/nds32_cmd.c +++ b/src/target/nds32_cmd.c @@ -681,8 +681,8 @@ static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *a { const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 3) { Jim_SetResultFormatted(goi.interp, @@ -692,12 +692,12 @@ static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *a int e; jim_wide address; - e = Jim_GetOpt_Wide(&goi, &address); + e = jim_getopt_wide(&goi, &address); if (e != JIM_OK) return e; jim_wide count; - e = Jim_GetOpt_Wide(&goi, &count); + e = jim_getopt_wide(&goi, &count); if (e != JIM_OK) return e; @@ -708,7 +708,7 @@ static int jim_nds32_bulk_write(Jim_Interp *interp, int argc, Jim_Obj * const *a jim_wide i; for (i = 0; i < count; i++) { jim_wide tmp; - e = Jim_GetOpt_Wide(&goi, &tmp); + e = jim_getopt_wide(&goi, &tmp); if (e != JIM_OK) { free(data); return e; @@ -738,8 +738,8 @@ static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const * { const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 3) { Jim_SetResultFormatted(goi.interp, @@ -749,7 +749,7 @@ static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const * int e; jim_wide num_of_pairs; - e = Jim_GetOpt_Wide(&goi, &num_of_pairs); + e = jim_getopt_wide(&goi, &num_of_pairs); if (e != JIM_OK) return e; @@ -765,12 +765,12 @@ static int jim_nds32_multi_write(Jim_Interp *interp, int argc, Jim_Obj * const * aice_set_command_mode(aice, AICE_COMMAND_MODE_PACK); for (i = 0; i < num_of_pairs; i++) { jim_wide tmp; - e = Jim_GetOpt_Wide(&goi, &tmp); + e = jim_getopt_wide(&goi, &tmp); if (e != JIM_OK) break; address = (uint32_t)tmp; - e = Jim_GetOpt_Wide(&goi, &tmp); + e = jim_getopt_wide(&goi, &tmp); if (e != JIM_OK) break; data = (uint32_t)tmp; @@ -792,8 +792,8 @@ static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *ar { const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 2) { Jim_SetResultFormatted(goi.interp, @@ -803,12 +803,12 @@ static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *ar int e; jim_wide address; - e = Jim_GetOpt_Wide(&goi, &address); + e = jim_getopt_wide(&goi, &address); if (e != JIM_OK) return e; jim_wide count; - e = Jim_GetOpt_Wide(&goi, &count); + e = jim_getopt_wide(&goi, &count); if (e != JIM_OK) return e; @@ -840,8 +840,8 @@ static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const * { const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 1) { Jim_SetResultFormatted(goi.interp, @@ -852,7 +852,7 @@ static int jim_nds32_read_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const * int e; const char *edm_sr_name; int edm_sr_name_len; - e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len); + e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len); if (e != JIM_OK) return e; @@ -888,8 +888,8 @@ static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const { const char *cmd_name = Jim_GetString(argv[0], NULL); - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 2) { Jim_SetResultFormatted(goi.interp, @@ -900,12 +900,12 @@ static int jim_nds32_write_edm_sr(Jim_Interp *interp, int argc, Jim_Obj * const int e; const char *edm_sr_name; int edm_sr_name_len; - e = Jim_GetOpt_String(&goi, &edm_sr_name, &edm_sr_name_len); + e = jim_getopt_string(&goi, &edm_sr_name, &edm_sr_name_len); if (e != JIM_OK) return e; jim_wide value; - e = Jim_GetOpt_Wide(&goi, &value); + e = jim_getopt_wide(&goi, &value); if (e != JIM_OK) return e; diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 8cfb227..3d40ebe 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -2573,7 +2573,7 @@ COMMAND_HANDLER(riscv_authdata_read) uint32_t value; if (r->authdata_read(target, &value, index) != ERROR_OK) return ERROR_FAIL; - command_print(CMD, "0x%" PRIx32, value); + command_print_sameline(CMD, "0x%08" PRIx32, value); return ERROR_OK; } else { LOG_ERROR("authdata_read is not implemented for this target."); @@ -3260,7 +3260,7 @@ static unsigned riscv_xlen_nonconst(struct target *target) return riscv_xlen(target); } -static unsigned riscv_data_bits(struct target *target) +static unsigned int riscv_data_bits(struct target *target) { RISCV_INFO(r); if (r->data_bits) diff --git a/src/target/startup.tcl b/src/target/startup.tcl index f128d3b..cd98d68 100644 --- a/src/target/startup.tcl +++ b/src/target/startup.tcl @@ -1,7 +1,7 @@ # Defines basic Tcl procs for OpenOCD target module proc new_target_name { } { - return [target number [expr [target count] - 1 ]] + return [target number [expr {[target count] - 1}]] } global in_process_reset @@ -16,7 +16,7 @@ proc ocd_process_reset { MODE } { } set in_process_reset 1 - set success [expr [catch {ocd_process_reset_inner $MODE} result]==0] + set success [expr {[catch {ocd_process_reset_inner $MODE} result] == 0}] set in_process_reset 0 if {$success} { @@ -30,18 +30,17 @@ proc ocd_process_reset_inner { MODE } { set targets [target names] # If this target must be halted... - set halt -1 - if { 0 == [string compare $MODE halt] } { - set halt 1 - } - if { 0 == [string compare $MODE init] } { - set halt 1; - } - if { 0 == [string compare $MODE run ] } { - set halt 0; - } - if { $halt < 0 } { - return -code error "Invalid mode: $MODE, must be one of: halt, init, or run"; + switch $MODE { + halt - + init { + set halt 1 + } + run { + set halt 0 + } + default { + return -code error "Invalid mode: $MODE, must be one of: halt, init, or run"; + } } # Target event handlers *might* change which TAPs are enabled @@ -130,14 +129,14 @@ proc ocd_process_reset_inner { MODE } { # Did we succeed? set s [$t curstate] - if { 0 != [string compare $s "halted" ] } { + if { $s != "halted" } { return -code error [format "TARGET: %s - Not halted" $t] } } } #Pass 2 - if needed "init" - if { 0 == [string compare init $MODE] } { + if { $MODE == "init" } { foreach t $targets { if {[using_jtag] && ![jtag tapisenabled [$t cget -chain-position]]} { continue @@ -208,31 +207,37 @@ proc init_board {} { } # smp_on/smp_off were already DEPRECATED in v0.11.0 through http://openocd.zylin.com/4615 +lappend _telnet_autocomplete_skip "aarch64 smp_on" proc "aarch64 smp_on" {args} { echo "DEPRECATED! use 'aarch64 smp on' not 'aarch64 smp_on'" eval aarch64 smp on $args } +lappend _telnet_autocomplete_skip "aarch64 smp_off" proc "aarch64 smp_off" {args} { echo "DEPRECATED! use 'aarch64 smp off' not 'aarch64 smp_off'" eval aarch64 smp off $args } +lappend _telnet_autocomplete_skip "cortex_a smp_on" proc "cortex_a smp_on" {args} { echo "DEPRECATED! use 'cortex_a smp on' not 'cortex_a smp_on'" eval cortex_a smp on $args } +lappend _telnet_autocomplete_skip "cortex_a smp_off" proc "cortex_a smp_off" {args} { echo "DEPRECATED! use 'cortex_a smp off' not 'cortex_a smp_off'" eval cortex_a smp off $args } +lappend _telnet_autocomplete_skip "mips_m4k smp_on" proc "mips_m4k smp_on" {args} { echo "DEPRECATED! use 'mips_m4k smp on' not 'mips_m4k smp_on'" eval mips_m4k smp on $args } +lappend _telnet_autocomplete_skip "mips_m4k smp_off" proc "mips_m4k smp_off" {args} { echo "DEPRECATED! use 'mips_m4k smp off' not 'mips_m4k smp_off'" eval mips_m4k smp off $args diff --git a/src/target/stm8.c b/src/target/stm8.c index e99b3c2..00b524e 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -1945,7 +1945,7 @@ static int stm8_run_algorithm(struct target *target, int num_mem_params, return ERROR_OK; } -static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) +static int stm8_jim_configure(struct target *target, struct jim_getopt_info *goi) { struct stm8_common *stm8 = target_to_stm8(target); jim_wide w; @@ -1954,7 +1954,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) arg = Jim_GetString(goi->argv[0], NULL); if (!strcmp(arg, "-blocksize")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -1964,7 +1964,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_ERR; } - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; @@ -1973,7 +1973,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_OK; } if (!strcmp(arg, "-flashstart")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -1983,7 +1983,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_ERR; } - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; @@ -1992,7 +1992,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_OK; } if (!strcmp(arg, "-flashend")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -2002,7 +2002,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_ERR; } - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; @@ -2011,7 +2011,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_OK; } if (!strcmp(arg, "-eepromstart")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -2021,7 +2021,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_ERR; } - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; @@ -2030,7 +2030,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_OK; } if (!strcmp(arg, "-eepromend")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -2040,7 +2040,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_ERR; } - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; @@ -2049,7 +2049,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_OK; } if (!strcmp(arg, "-optionstart")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -2059,7 +2059,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_ERR; } - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; @@ -2068,7 +2068,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_OK; } if (!strcmp(arg, "-optionend")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -2078,7 +2078,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_ERR; } - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; @@ -2087,7 +2087,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_OK; } if (!strcmp(arg, "-enable_step_irq")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -2096,7 +2096,7 @@ static int stm8_jim_configure(struct target *target, Jim_GetOptInfo *goi) return JIM_OK; } if (!strcmp(arg, "-enable_stm8l")) { - e = Jim_GetOpt_String(goi, &arg, NULL); + e = jim_getopt_string(goi, &arg, NULL); if (e != JIM_OK) return e; @@ -2159,7 +2159,7 @@ static const struct command_registration stm8_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -const struct command_registration stm8_command_handlers[] = { +static const struct command_registration stm8_command_handlers[] = { { .name = "stm8", .mode = COMMAND_ANY, diff --git a/src/target/stm8.h b/src/target/stm8.h index da7f1f1..b18ff58 100644 --- a/src/target/stm8.h +++ b/src/target/stm8.h @@ -70,6 +70,4 @@ target_to_stm8(struct target *target) return target->arch_info; } -const struct command_registration stm8_command_handlers[]; - #endif /* OPENOCD_TARGET_STM8_H */ diff --git a/src/target/target.c b/src/target/target.c index 34016a3..d953bf4 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -158,7 +158,7 @@ static LIST_HEAD(target_reset_callback_list); static LIST_HEAD(target_trace_callback_list); static const int polling_interval = TARGET_DEFAULT_POLLING_INTERVAL; -static const Jim_Nvp nvp_assert[] = { +static const struct jim_nvp nvp_assert[] = { { .name = "assert", NVP_ASSERT }, { .name = "deassert", NVP_DEASSERT }, { .name = "T", NVP_ASSERT }, @@ -168,7 +168,7 @@ static const Jim_Nvp nvp_assert[] = { { .name = NULL, .value = -1 } }; -static const Jim_Nvp nvp_error_target[] = { +static const struct jim_nvp nvp_error_target[] = { { .value = ERROR_TARGET_INVALID, .name = "err-invalid" }, { .value = ERROR_TARGET_INIT_FAILED, .name = "err-init-failed" }, { .value = ERROR_TARGET_TIMEOUT, .name = "err-timeout" }, @@ -185,16 +185,16 @@ static const Jim_Nvp nvp_error_target[] = { static const char *target_strerror_safe(int err) { - const Jim_Nvp *n; + const struct jim_nvp *n; - n = Jim_Nvp_value2name_simple(nvp_error_target, err); + n = jim_nvp_value2name_simple(nvp_error_target, err); if (n->name == NULL) return "unknown"; else return n->name; } -static const Jim_Nvp nvp_target_event[] = { +static const struct jim_nvp nvp_target_event[] = { { .value = TARGET_EVENT_GDB_HALT, .name = "gdb-halt" }, { .value = TARGET_EVENT_HALTED, .name = "halted" }, @@ -237,7 +237,7 @@ static const Jim_Nvp nvp_target_event[] = { { .name = NULL, .value = -1 } }; -static const Jim_Nvp nvp_target_state[] = { +static const struct jim_nvp nvp_target_state[] = { { .name = "unknown", .value = TARGET_UNKNOWN }, { .name = "running", .value = TARGET_RUNNING }, { .name = "halted", .value = TARGET_HALTED }, @@ -246,7 +246,7 @@ static const Jim_Nvp nvp_target_state[] = { { .name = NULL, .value = -1 }, }; -static const Jim_Nvp nvp_target_debug_reason[] = { +static const struct jim_nvp nvp_target_debug_reason[] = { { .name = "debug-request", .value = DBG_REASON_DBGRQ }, { .name = "breakpoint", .value = DBG_REASON_BREAKPOINT }, { .name = "watchpoint", .value = DBG_REASON_WATCHPOINT }, @@ -259,7 +259,7 @@ static const Jim_Nvp nvp_target_debug_reason[] = { { .name = NULL, .value = -1 }, }; -static const Jim_Nvp nvp_target_endian[] = { +static const struct jim_nvp nvp_target_endian[] = { { .name = "big", .value = TARGET_BIG_ENDIAN }, { .name = "little", .value = TARGET_LITTLE_ENDIAN }, { .name = "be", .value = TARGET_BIG_ENDIAN }, @@ -267,7 +267,7 @@ static const Jim_Nvp nvp_target_endian[] = { { .name = NULL, .value = -1 }, }; -static const Jim_Nvp nvp_reset_modes[] = { +static const struct jim_nvp nvp_reset_modes[] = { { .name = "unknown", .value = RESET_UNKNOWN }, { .name = "run", .value = RESET_RUN }, { .name = "halt", .value = RESET_HALT }, @@ -279,7 +279,7 @@ const char *debug_reason_name(struct target *t) { const char *cp; - cp = Jim_Nvp_value2name_simple(nvp_target_debug_reason, + cp = jim_nvp_value2name_simple(nvp_target_debug_reason, t->debug_reason)->name; if (!cp) { LOG_ERROR("Invalid debug reason: %d", (int)(t->debug_reason)); @@ -291,7 +291,7 @@ const char *debug_reason_name(struct target *t) const char *target_state_name(struct target *t) { const char *cp; - cp = Jim_Nvp_value2name_simple(nvp_target_state, t->state)->name; + cp = jim_nvp_value2name_simple(nvp_target_state, t->state)->name; if (!cp) { LOG_ERROR("Invalid target state: %d", (int)(t->state)); cp = "(*BUG*unknown*BUG*)"; @@ -306,7 +306,7 @@ const char *target_state_name(struct target *t) const char *target_event_name(enum target_event event) { const char *cp; - cp = Jim_Nvp_value2name_simple(nvp_target_event, event)->name; + cp = jim_nvp_value2name_simple(nvp_target_event, event)->name; if (!cp) { LOG_ERROR("Invalid target event: %d", (int)(event)); cp = "(*BUG*unknown*BUG*)"; @@ -317,7 +317,7 @@ const char *target_event_name(enum target_event event) const char *target_reset_mode_name(enum target_reset_mode reset_mode) { const char *cp; - cp = Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode)->name; + cp = jim_nvp_value2name_simple(nvp_reset_modes, reset_mode)->name; if (!cp) { LOG_ERROR("Invalid target reset mode: %d", (int)(reset_mode)); cp = "(*BUG*unknown*BUG*)"; @@ -661,8 +661,8 @@ static int target_process_reset(struct command_invocation *cmd, enum target_rese { char buf[100]; int retval; - Jim_Nvp *n; - n = Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode); + struct jim_nvp *n; + n = jim_nvp_value2name_simple(nvp_reset_modes, reset_mode); if (n->name == NULL) { LOG_ERROR("invalid reset mode"); return ERROR_FAIL; @@ -1506,7 +1506,7 @@ unsigned target_address_bits(struct target *target) return 32; } -unsigned target_data_bits(struct target *target) +unsigned int target_data_bits(struct target *target) { if (target->type->data_bits) return target->type->data_bits(target); @@ -1829,7 +1829,7 @@ int target_call_event_callbacks(struct target *target, enum target_event event) } LOG_DEBUG("target event %i (%s) for core %s", event, - Jim_Nvp_value2name_simple(nvp_target_event, event)->name, + jim_nvp_value2name_simple(nvp_target_event, event)->name, target_name(target)); target_handle_event(target, event); @@ -1848,7 +1848,7 @@ int target_call_reset_callbacks(struct target *target, enum target_reset_mode re struct target_reset_callback *callback; LOG_DEBUG("target reset %i (%s)", reset_mode, - Jim_Nvp_value2name_simple(nvp_reset_modes, reset_mode)->name); + jim_nvp_value2name_simple(nvp_reset_modes, reset_mode)->name); list_for_each_entry(callback, &target_reset_callback_list, list) callback->callback(target, reset_mode, callback->priv); @@ -2415,11 +2415,12 @@ static int target_write_buffer_default(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer) { uint32_t size; + unsigned int data_bytes = target_data_bits(target) / 8; /* Align up to maximum bytes. The loop condition makes sure the next pass * will have something to do with the size we leave to it. */ for (size = 1; - size < target_data_bits(target) / 8 && count >= size * 2 + (address & size); + size < data_bytes && count >= size * 2 + (address & size); size *= 2) { if (address & size) { int retval = target_write_memory(target, address, size, 1, buffer); @@ -2478,11 +2479,12 @@ int target_read_buffer(struct target *target, target_addr_t address, uint32_t si static int target_read_buffer_default(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer) { uint32_t size; + unsigned int data_bytes = target_data_bits(target) / 8; /* Align up to maximum bytes. The loop condition makes sure the next pass * will have something to do with the size we leave to it. */ for (size = 1; - size < target_data_bits(target) / 8 && count >= size * 2 + (address & size); + size < data_bytes && count >= size * 2 + (address & size); size *= 2) { if (address & size) { int retval = target_read_memory(target, address, size, 1, buffer); @@ -2876,7 +2878,7 @@ COMMAND_HANDLER(handle_targets_command) marker, target_name(target), target_type_name(target), - Jim_Nvp_value2name_simple(nvp_target_endian, + jim_nvp_value2name_simple(nvp_target_endian, target->endianness)->name, target->tap->dotted_name, state); @@ -3269,7 +3271,7 @@ int target_wait_state(struct target *target, enum target_state state, int ms) once = false; then = timeval_ms(); LOG_DEBUG("waiting for target %s...", - Jim_Nvp_value2name_simple(nvp_target_state, state)->name); + jim_nvp_value2name_simple(nvp_target_state, state)->name); } if (cur-then > 500) @@ -3277,7 +3279,7 @@ int target_wait_state(struct target *target, enum target_state state, int ms) if ((cur-then) > ms) { LOG_ERROR("timed out while waiting for target %s", - Jim_Nvp_value2name_simple(nvp_target_state, state)->name); + jim_nvp_value2name_simple(nvp_target_state, state)->name); return ERROR_FAIL; } } @@ -3327,8 +3329,8 @@ COMMAND_HANDLER(handle_reset_command) enum target_reset_mode reset_mode = RESET_RUN; if (CMD_ARGC == 1) { - const Jim_Nvp *n; - n = Jim_Nvp_name2value_simple(nvp_reset_modes, CMD_ARGV[0]); + const struct jim_nvp *n; + n = jim_nvp_name2value_simple(nvp_reset_modes, CMD_ARGV[0]); if ((n->name == NULL) || (n->value == RESET_UNKNOWN)) return ERROR_COMMAND_SYNTAX_ERROR; reset_mode = n->value; @@ -4807,7 +4809,7 @@ void target_handle_event(struct target *target, enum target_event e) target_name(target), target_type_name(target), e, - Jim_Nvp_value2name_simple(nvp_target_event, e)->name, + jim_nvp_value2name_simple(nvp_target_event, e)->name, Jim_GetString(teap->body, NULL)); /* Override current target by the target an event @@ -4831,7 +4833,7 @@ void target_handle_event(struct target *target, enum target_event e) if (retval != JIM_OK) { Jim_MakeErrorMessage(teap->interp); LOG_USER("Error executing event %s on target %s:\n%s", - Jim_Nvp_value2name_simple(nvp_target_event, e)->name, + jim_nvp_value2name_simple(nvp_target_event, e)->name, target_name(target), Jim_GetString(Jim_GetResult(teap->interp), NULL)); /* clean both error code and stacktrace before return */ @@ -4872,7 +4874,7 @@ enum target_cfg_param { TCFG_GDB_MAX_CONNECTIONS, }; -static Jim_Nvp nvp_config_opts[] = { +static struct jim_nvp nvp_config_opts[] = { { .name = "-type", .value = TCFG_TYPE }, { .name = "-event", .value = TCFG_EVENT }, { .name = "-work-area-virt", .value = TCFG_WORK_AREA_VIRT }, @@ -4890,9 +4892,9 @@ static Jim_Nvp nvp_config_opts[] = { { .name = NULL, .value = -1 } }; -static int target_configure(Jim_GetOptInfo *goi, struct target *target) +static int target_configure(struct jim_getopt_info *goi, struct target *target) { - Jim_Nvp *n; + struct jim_nvp *n; Jim_Obj *o; jim_wide w; int e; @@ -4900,7 +4902,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) /* parse config or cget options ... */ while (goi->argc > 0) { Jim_SetEmptyResult(goi->interp); - /* Jim_GetOpt_Debug(goi); */ + /* jim_getopt_debug(goi); */ if (target->type->target_jim_configure) { /* target defines a configure function */ @@ -4916,9 +4918,9 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) } /* otherwise we 'continue' below */ } - e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n); + e = jim_getopt_nvp(goi, nvp_config_opts, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0); + jim_getopt_nvp_unknown(goi, nvp_config_opts, 0); return e; } switch (n->value) { @@ -4947,9 +4949,9 @@ no_params: return JIM_ERR; } - e = Jim_GetOpt_Nvp(goi, nvp_target_event, &n); + e = jim_getopt_nvp(goi, nvp_target_event, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_target_event, 1); + jim_getopt_nvp_unknown(goi, nvp_target_event, 1); return e; } @@ -4990,7 +4992,7 @@ no_params: } teap->event = n->value; teap->interp = goi->interp; - Jim_GetOpt_Obj(goi, &o); + jim_getopt_obj(goi, &o); if (teap->body) Jim_DecrRefCount(teap->interp, teap->body); teap->body = Jim_DuplicateObj(goi->interp, o); @@ -5026,7 +5028,7 @@ no_params: case TCFG_WORK_AREA_VIRT: if (goi->isconfigure) { target_free_all_working_areas(target); - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; target->working_area_virt = w; @@ -5042,7 +5044,7 @@ no_params: case TCFG_WORK_AREA_PHYS: if (goi->isconfigure) { target_free_all_working_areas(target); - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; target->working_area_phys = w; @@ -5058,7 +5060,7 @@ no_params: case TCFG_WORK_AREA_SIZE: if (goi->isconfigure) { target_free_all_working_areas(target); - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; target->working_area_size = w; @@ -5073,7 +5075,7 @@ no_params: case TCFG_WORK_AREA_BACKUP: if (goi->isconfigure) { target_free_all_working_areas(target); - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; /* make this exactly 1 or 0 */ @@ -5089,9 +5091,9 @@ no_params: case TCFG_ENDIAN: if (goi->isconfigure) { - e = Jim_GetOpt_Nvp(goi, nvp_target_endian, &n); + e = jim_getopt_nvp(goi, nvp_target_endian, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(goi, nvp_target_endian, 1); + jim_getopt_nvp_unknown(goi, nvp_target_endian, 1); return e; } target->endianness = n->value; @@ -5099,10 +5101,10 @@ no_params: if (goi->argc != 0) goto no_params; } - n = Jim_Nvp_value2name_simple(nvp_target_endian, target->endianness); + n = jim_nvp_value2name_simple(nvp_target_endian, target->endianness); if (n->name == NULL) { target->endianness = TARGET_LITTLE_ENDIAN; - n = Jim_Nvp_value2name_simple(nvp_target_endian, target->endianness); + n = jim_nvp_value2name_simple(nvp_target_endian, target->endianness); } Jim_SetResultString(goi->interp, n->name, -1); /* loop for more */ @@ -5110,7 +5112,7 @@ no_params: case TCFG_COREID: if (goi->isconfigure) { - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; target->coreid = (int32_t)w; @@ -5134,7 +5136,7 @@ no_params: } target_free_all_working_areas(target); - e = Jim_GetOpt_Obj(goi, &o_t); + e = jim_getopt_obj(goi, &o_t); if (e != JIM_OK) return e; tap = jtag_tap_by_jim_obj(goi->interp, o_t); @@ -5151,7 +5153,7 @@ no_params: break; case TCFG_DBGBASE: if (goi->isconfigure) { - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; target->dbgbase = (uint32_t)w; @@ -5188,7 +5190,7 @@ no_params: } const char *s; - e = Jim_GetOpt_String(goi, &s, NULL); + e = jim_getopt_string(goi, &s, NULL); if (e != JIM_OK) return e; free(target->gdb_port_override); @@ -5197,7 +5199,7 @@ no_params: if (goi->argc != 0) goto no_params; } - Jim_SetResultString(goi->interp, target->gdb_port_override ? : "undefined", -1); + Jim_SetResultString(goi->interp, target->gdb_port_override ? target->gdb_port_override : "undefined", -1); /* loop for more */ break; @@ -5205,11 +5207,11 @@ no_params: if (goi->isconfigure) { struct command_context *cmd_ctx = current_command_context(goi->interp); if (cmd_ctx->mode != COMMAND_CONFIG) { - Jim_SetResultString(goi->interp, "-gdb-max-conenctions must be configured before 'init'", -1); + Jim_SetResultString(goi->interp, "-gdb-max-connections must be configured before 'init'", -1); return JIM_ERR; } - e = Jim_GetOpt_Wide(goi, &w); + e = jim_getopt_wide(goi, &w); if (e != JIM_OK) return e; target->gdb_max_connections = (w < 0) ? CONNECTION_LIMIT_UNLIMITED : (int)w; @@ -5230,9 +5232,9 @@ no_params: static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv) { struct command *c = jim_to_command(interp); - Jim_GetOptInfo goi; + struct jim_getopt_info goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); goi.isconfigure = !strcmp(c->name, "configure"); if (goi.argc < 1) { Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, @@ -5273,8 +5275,8 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv { bool allow_defer = false; - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc > 1) { const char *cmd_name = Jim_GetString(argv[0], NULL); Jim_SetResultFormatted(goi.interp, @@ -5285,7 +5287,7 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv strcmp(Jim_GetString(argv[1], NULL), "allow-defer") == 0) { /* consume it */ Jim_Obj *obj; - int e = Jim_GetOpt_Obj(&goi, &obj); + int e = jim_getopt_obj(&goi, &obj); if (e != JIM_OK) return e; allow_defer = true; @@ -5369,8 +5371,8 @@ static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc != 2) { Jim_WrongNumArgs(interp, 0, argv, @@ -5378,15 +5380,15 @@ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } - Jim_Nvp *n; - int e = Jim_GetOpt_Nvp(&goi, nvp_assert, &n); + struct jim_nvp *n; + int e = jim_getopt_nvp(&goi, nvp_assert, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(&goi, nvp_assert, 1); + jim_getopt_nvp_unknown(&goi, nvp_assert, 1); return e; } /* the halt or not param */ jim_wide a; - e = Jim_GetOpt_Wide(&goi, &a); + e = jim_getopt_wide(&goi, &a); if (e != JIM_OK) return e; @@ -5407,7 +5409,7 @@ static int jim_target_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv) target_reset_examined(target); /* determine if we should halt or not. */ - target->reset_halt = !!a; + target->reset_halt = (a != 0); /* When this happens - all workareas are invalid. */ target_free_all_working_areas_restore(target, 0); @@ -5436,8 +5438,8 @@ static int jim_target_halt(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); /* params: <name> statename timeoutmsecs */ if (goi.argc != 2) { @@ -5447,14 +5449,14 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a return JIM_ERR; } - Jim_Nvp *n; - int e = Jim_GetOpt_Nvp(&goi, nvp_target_state, &n); + struct jim_nvp *n; + int e = jim_getopt_nvp(&goi, nvp_target_state, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(&goi, nvp_target_state, 1); + jim_getopt_nvp_unknown(&goi, nvp_target_state, 1); return e; } jim_wide a; - e = Jim_GetOpt_Wide(&goi, &a); + e = jim_getopt_wide(&goi, &a); if (e != JIM_OK) return e; struct command_context *cmd_ctx = current_command_context(interp); @@ -5489,7 +5491,7 @@ COMMAND_HANDLER(handle_target_event_list) command_print(CMD, "------------------------- | " "----------------------------------------"); while (teap) { - Jim_Nvp *opt = Jim_Nvp_value2name_simple(nvp_target_event, teap->event); + struct jim_nvp *opt = jim_nvp_value2name_simple(nvp_target_event, teap->event); command_print(CMD, "%-25s | %s", opt->name, Jim_GetString(teap->body, NULL)); teap = teap->next; @@ -5511,17 +5513,17 @@ static int jim_target_current_state(Jim_Interp *interp, int argc, Jim_Obj *const } static int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc != 1) { const char *cmd_name = Jim_GetString(argv[0], NULL); Jim_SetResultFormatted(goi.interp, "%s <eventname>", cmd_name); return JIM_ERR; } - Jim_Nvp *n; - int e = Jim_GetOpt_Nvp(&goi, nvp_target_event, &n); + struct jim_nvp *n; + int e = jim_getopt_nvp(&goi, nvp_target_event, &n); if (e != JIM_OK) { - Jim_GetOpt_NvpUnknown(&goi, nvp_target_event, 1); + jim_getopt_nvp_unknown(&goi, nvp_target_event, 1); return e; } struct command_context *cmd_ctx = current_command_context(interp); @@ -5690,7 +5692,7 @@ static const struct command_registration target_instance_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -static int target_create(Jim_GetOptInfo *goi) +static int target_create(struct jim_getopt_info *goi) { Jim_Obj *new_cmd; Jim_Cmd *cmd; @@ -5709,7 +5711,7 @@ static int target_create(Jim_GetOptInfo *goi) } /* COMMAND */ - Jim_GetOpt_Obj(goi, &new_cmd); + jim_getopt_obj(goi, &new_cmd); /* does this command exist? */ cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG); if (cmd) { @@ -5719,7 +5721,7 @@ static int target_create(Jim_GetOptInfo *goi) } /* TYPE */ - e = Jim_GetOpt_String(goi, &cp, NULL); + e = jim_getopt_string(goi, &cp, NULL); if (e != JIM_OK) return e; struct transport *tr = get_current_transport(); @@ -6025,8 +6027,8 @@ static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - Jim_GetOptInfo goi; - Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, interp, argc - 1, argv + 1); if (goi.argc < 3) { Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, "<name> <target_type> [<target_options> ...]"); @@ -6711,15 +6713,15 @@ static const struct command_registration target_exec_command_handlers[] = { .handler = handle_target_reset_nag, .mode = COMMAND_ANY, .help = "Nag after each reset about options that could have been " - "enabled to improve performance. ", + "enabled to improve performance.", .usage = "['enable'|'disable']", }, { .name = "ps", .handler = handle_ps_command, .mode = COMMAND_EXEC, - .help = "list all tasks ", - .usage = " ", + .help = "list all tasks", + .usage = "", }, { .name = "test_mem_access", diff --git a/src/target/target.h b/src/target/target.h index 9389690..2dc9e9c 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -157,7 +157,7 @@ struct target { struct target_event_action *event_action; - int reset_halt; /* attempt resetting the CPU into the halted mode? */ + bool reset_halt; /* attempt resetting the CPU into the halted mode? */ target_addr_t working_area; /* working area (initialised RAM). Evaluated * upon first allocation from virtual/physical address. */ bool working_area_virt_spec; /* virtual address specified? */ @@ -689,7 +689,7 @@ unsigned target_address_bits(struct target *target); * * This routine is a wrapper for target->type->data_bits. */ -unsigned target_data_bits(struct target *target); +unsigned int target_data_bits(struct target *target); /** Return the *name* of this targets current state */ const char *target_state_name(struct target *target); diff --git a/src/target/target_type.h b/src/target/target_type.h index f7b4c94..cf30cf8 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -79,7 +79,7 @@ struct target_type { * state correctly. * * Otherwise the following would fail, as there will not - * be any "poll" invoked inbetween the "reset run" and + * be any "poll" invoked between the "reset run" and * "halt". * * reset run; halt @@ -210,11 +210,11 @@ struct target_type { /* called for various config parameters */ /* returns JIM_CONTINUE - if option not understood */ /* otherwise: JIM_OK, or JIM_ERR, */ - int (*target_jim_configure)(struct target *target, Jim_GetOptInfo *goi); + int (*target_jim_configure)(struct target *target, struct jim_getopt_info *goi); /* target commands specifically handled by the target */ /* returns JIM_OK, or JIM_ERR, or JIM_CONTINUE - if option not understood */ - int (*target_jim_commands)(struct target *target, Jim_GetOptInfo *goi); + int (*target_jim_commands)(struct target *target, struct jim_getopt_info *goi); /** * This method is used to perform target setup that requires @@ -299,7 +299,7 @@ struct target_type { /* Return the number of system bus data bits this target supports. This * will typically be 32 for 32-bit targets, and 64 for 64-bit targets. If * not implemented, it's assumed to be 32. */ - unsigned (*data_bits)(struct target *target); + unsigned int (*data_bits)(struct target *target); }; #endif /* OPENOCD_TARGET_TARGET_TYPE_H */ diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c index 2a7b56d..8237849 100644 --- a/src/xsvf/xsvf.c +++ b/src/xsvf/xsvf.c @@ -1057,7 +1057,7 @@ int xsvf_register_commands(struct command_context *cmd_ctx) /* -PSUEDO-Code from Xilinx Appnote XAPP067.pdf : +PSEUDO-Code from Xilinx Appnote XAPP067.pdf : the following pseudo code clarifies the intent of the xrepeat support.The flow given is for the entire processing of an SVF file, not an XSVF file. |