From 076b4d708e14a830cffee64d39ad0a1940e13e2f Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 3 Jun 2021 23:11:18 +0200 Subject: [PATCH 01/27] target/cortex_a: Use bool data type Change-Id: Ieea3dc05809263aa0eba5125d52fef3fe77e9c5a Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/6289 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/cortex_a.c | 22 +++++++++++----------- src/target/cortex_a.h | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 6b76656b9..ec02d179f 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1290,7 +1290,7 @@ static int cortex_a_set_breakpoint(struct target *target, control = ((matchmode & 0x7) << 20) | (byte_addr_select << 5) | (3 << 1) | 1; - brp_list[brp_i].used = 1; + brp_list[brp_i].used = true; brp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC); brp_list[brp_i].control = control; retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base @@ -1384,7 +1384,7 @@ static int cortex_a_set_context_breakpoint(struct target *target, control = ((matchmode & 0x7) << 20) | (byte_addr_select << 5) | (3 << 1) | 1; - brp_list[brp_i].used = 1; + brp_list[brp_i].used = true; brp_list[brp_i].value = (breakpoint->asid); brp_list[brp_i].control = control; retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base @@ -1450,7 +1450,7 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi | (0 << 14) | (CTX_byte_addr_select << 5) | (3 << 1) | 1; - brp_list[brp_1].used = 1; + brp_list[brp_1].used = true; brp_list[brp_1].value = (breakpoint->asid); brp_list[brp_1].control = control_CTX; retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base @@ -1468,7 +1468,7 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi | (brp_1 << 16) | (IVA_byte_addr_select << 5) | (3 << 1) | 1; - brp_list[brp_2].used = 1; + brp_list[brp_2].used = true; brp_list[brp_2].value = (breakpoint->address & 0xFFFFFFFC); brp_list[brp_2].control = control_IVA; retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base @@ -1507,7 +1507,7 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b } LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i, brp_list[brp_i].control, brp_list[brp_i].value); - brp_list[brp_i].used = 0; + brp_list[brp_i].used = false; brp_list[brp_i].value = 0; brp_list[brp_i].control = 0; retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base @@ -1526,7 +1526,7 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b } LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_j, brp_list[brp_j].control, brp_list[brp_j].value); - brp_list[brp_j].used = 0; + brp_list[brp_j].used = false; brp_list[brp_j].value = 0; brp_list[brp_j].control = 0; retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base @@ -1551,7 +1551,7 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b } LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, brp_i, brp_list[brp_i].control, brp_list[brp_i].value); - brp_list[brp_i].used = 0; + brp_list[brp_i].used = false; brp_list[brp_i].value = 0; brp_list[brp_i].control = 0; retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base @@ -1753,7 +1753,7 @@ static int cortex_a_set_watchpoint(struct target *target, struct watchpoint *wat (byte_address_select << 5) | (load_store_access_control << 3) | (0x3 << 1) | 1; - wrp_list[wrp_i].used = 1; + wrp_list[wrp_i].used = true; wrp_list[wrp_i].value = address; wrp_list[wrp_i].control = control; @@ -1803,7 +1803,7 @@ static int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *w } 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].used = false; wrp_list[wrp_i].value = 0; wrp_list[wrp_i].control = 0; retval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base @@ -3033,7 +3033,7 @@ static int cortex_a_examine_first(struct target *target) cortex_a->brp_list = calloc(cortex_a->brp_num, sizeof(struct cortex_a_brp)); /* cortex_a->brb_enabled = ????; */ for (i = 0; i < cortex_a->brp_num; i++) { - cortex_a->brp_list[i].used = 0; + cortex_a->brp_list[i].used = false; if (i < (cortex_a->brp_num-cortex_a->brp_num_context)) cortex_a->brp_list[i].type = BRP_NORMAL; else @@ -3051,7 +3051,7 @@ static int cortex_a_examine_first(struct target *target) 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].used = false; cortex_a->wrp_list[i].value = 0; cortex_a->wrp_list[i].control = 0; cortex_a->wrp_list[i].WRPn = i; diff --git a/src/target/cortex_a.h b/src/target/cortex_a.h index dd135ec97..84e42a706 100644 --- a/src/target/cortex_a.h +++ b/src/target/cortex_a.h @@ -64,7 +64,7 @@ enum cortex_a_dacrfixup_mode { }; struct cortex_a_brp { - int used; + bool used; int type; uint32_t value; uint32_t control; @@ -72,7 +72,7 @@ struct cortex_a_brp { }; struct cortex_a_wrp { - int used; + bool used; uint32_t value; uint32_t control; uint8_t WRPn; From f2958fc04bd879393fa743860478834e234f05d0 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Fri, 28 May 2021 13:38:50 -0700 Subject: [PATCH 02/27] Add remote bitbang write buffer. Change 7dd323b26 reduced remote bitbang performance a lot. This change gets most of that performance back again, by reintroducing a write buffer. Performance numbers collected using DebugBreakpoint test from riscv-tests/debug against a single 64-bit spike (RISC-V simulator) instance. (Ubuntu 20.04.2, AMD Ryzen 5 3600) Before Windows support was added: 3.09s After Windows support was added: 12.67s After this change: 4.69s Signed-off-by: Tim Newsome Change-Id: I72ff4912cbbf316a30ef065e5b8f461a555f06cc Reviewed-on: http://openocd.zylin.com/6283 Tested-by: jenkins Reviewed-by: Jan Matyas Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- src/jtag/drivers/remote_bitbang.c | 123 +++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 37 deletions(-) diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c index f7b88303b..57f0c6e07 100644 --- a/src/jtag/drivers/remote_bitbang.c +++ b/src/jtag/drivers/remote_bitbang.c @@ -36,17 +36,19 @@ static char *remote_bitbang_host; static char *remote_bitbang_port; static int remote_bitbang_fd; +static uint8_t remote_bitbang_send_buf[512]; +static unsigned int remote_bitbang_send_buf_used; /* Circular buffer. When start == end, the buffer is empty. */ -static char remote_bitbang_buf[64]; -static unsigned remote_bitbang_start; -static unsigned remote_bitbang_end; +static char remote_bitbang_recv_buf[64]; +static unsigned int remote_bitbang_recv_buf_start; +static unsigned int remote_bitbang_recv_buf_end; -static int remote_bitbang_buf_full(void) +static bool remote_bitbang_buf_full(void) { - return remote_bitbang_end == - ((remote_bitbang_start + sizeof(remote_bitbang_buf) - 1) % - sizeof(remote_bitbang_buf)); + return remote_bitbang_recv_buf_end == + ((remote_bitbang_recv_buf_start + sizeof(remote_bitbang_recv_buf) - 1) % + sizeof(remote_bitbang_recv_buf)); } /* Read any incoming data, placing it into the buffer. */ @@ -54,23 +56,23 @@ static int remote_bitbang_fill_buf(void) { socket_nonblock(remote_bitbang_fd); while (!remote_bitbang_buf_full()) { - unsigned contiguous_available_space; - if (remote_bitbang_end >= remote_bitbang_start) { - contiguous_available_space = sizeof(remote_bitbang_buf) - - remote_bitbang_end; - if (remote_bitbang_start == 0) + unsigned int contiguous_available_space; + if (remote_bitbang_recv_buf_end >= remote_bitbang_recv_buf_start) { + contiguous_available_space = sizeof(remote_bitbang_recv_buf) - + remote_bitbang_recv_buf_end; + if (remote_bitbang_recv_buf_start == 0) contiguous_available_space -= 1; } else { - contiguous_available_space = remote_bitbang_start - - remote_bitbang_end - 1; + contiguous_available_space = remote_bitbang_recv_buf_start - + remote_bitbang_recv_buf_end - 1; } ssize_t count = read_socket(remote_bitbang_fd, - remote_bitbang_buf + remote_bitbang_end, + remote_bitbang_recv_buf + remote_bitbang_recv_buf_end, contiguous_available_space); if (count > 0) { - remote_bitbang_end += count; - if (remote_bitbang_end == sizeof(remote_bitbang_buf)) - remote_bitbang_end = 0; + remote_bitbang_recv_buf_end += count; + if (remote_bitbang_recv_buf_end == sizeof(remote_bitbang_recv_buf)) + remote_bitbang_recv_buf_end = 0; } else if (count == 0) { return ERROR_OK; } else if (count < 0) { @@ -90,20 +92,43 @@ static int remote_bitbang_fill_buf(void) return ERROR_OK; } -static int remote_bitbang_putc(int c) +static int remote_bitbang_flush(void) { - char buf = c; - ssize_t count = write_socket(remote_bitbang_fd, &buf, sizeof(buf)); - if (count < 0) { - log_socket_error("remote_bitbang_putc"); - return ERROR_FAIL; + if (remote_bitbang_send_buf_used <= 0) + return ERROR_OK; + + unsigned int offset = 0; + while (offset < remote_bitbang_send_buf_used) { + ssize_t written = write_socket(remote_bitbang_fd, remote_bitbang_send_buf + offset, + remote_bitbang_send_buf_used - offset); + if (written < 0) { + log_socket_error("remote_bitbang_putc"); + remote_bitbang_send_buf_used = 0; + return ERROR_FAIL; + } + offset += written; } + remote_bitbang_send_buf_used = 0; + return ERROR_OK; +} + +typedef enum { + NO_FLUSH, + FLUSH_SEND_BUF +} flush_bool_t; + +static int remote_bitbang_queue(int c, flush_bool_t flush) +{ + remote_bitbang_send_buf[remote_bitbang_send_buf_used++] = c; + if (flush == FLUSH_SEND_BUF || + remote_bitbang_send_buf_used >= ARRAY_SIZE(remote_bitbang_send_buf)) + return remote_bitbang_flush(); return ERROR_OK; } static int remote_bitbang_quit(void) { - if (remote_bitbang_putc('Q') == ERROR_FAIL) + if (remote_bitbang_queue('Q', FLUSH_SEND_BUF) == ERROR_FAIL) return ERROR_FAIL; if (close_socket(remote_bitbang_fd) != 0) { @@ -135,6 +160,9 @@ static bb_value_t char_to_int(int c) /* Get the next read response. */ static bb_value_t remote_bitbang_rread(void) { + if (remote_bitbang_flush() != ERROR_OK) + return ERROR_FAIL; + /* Enable blocking access. */ socket_block(remote_bitbang_fd); char c; @@ -154,15 +182,19 @@ static int remote_bitbang_sample(void) if (remote_bitbang_fill_buf() != ERROR_OK) return ERROR_FAIL; assert(!remote_bitbang_buf_full()); - return remote_bitbang_putc('R'); + return remote_bitbang_queue('R', NO_FLUSH); } static bb_value_t remote_bitbang_read_sample(void) { - if (remote_bitbang_start != remote_bitbang_end) { - int c = remote_bitbang_buf[remote_bitbang_start]; - remote_bitbang_start = - (remote_bitbang_start + 1) % sizeof(remote_bitbang_buf); + if (remote_bitbang_recv_buf_start == remote_bitbang_recv_buf_end) { + if (remote_bitbang_fill_buf() != ERROR_OK) + return ERROR_FAIL; + } + if (remote_bitbang_recv_buf_start != remote_bitbang_recv_buf_end) { + int c = remote_bitbang_recv_buf[remote_bitbang_recv_buf_start]; + remote_bitbang_recv_buf_start = + (remote_bitbang_recv_buf_start + 1) % sizeof(remote_bitbang_recv_buf); return char_to_int(c); } return remote_bitbang_rread(); @@ -171,23 +203,25 @@ static bb_value_t remote_bitbang_read_sample(void) static int remote_bitbang_write(int tck, int tms, int tdi) { char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0)); - return remote_bitbang_putc(c); + return remote_bitbang_queue(c, NO_FLUSH); } static int remote_bitbang_reset(int trst, int srst) { char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0)); - return remote_bitbang_putc(c); + /* Always flush the send buffer on reset, because the reset call need not be + * followed by jtag_execute_queue(). */ + return remote_bitbang_queue(c, FLUSH_SEND_BUF); } static int remote_bitbang_blink(int on) { char c = on ? 'B' : 'b'; - return remote_bitbang_putc(c); + return remote_bitbang_queue(c, FLUSH_SEND_BUF); } static struct bitbang_interface remote_bitbang_bitbang = { - .buf_size = sizeof(remote_bitbang_buf) - 1, + .buf_size = sizeof(remote_bitbang_recv_buf) - 1, .sample = &remote_bitbang_sample, .read_sample = &remote_bitbang_read_sample, .write = &remote_bitbang_write, @@ -268,8 +302,8 @@ static int remote_bitbang_init(void) { bitbang_interface = &remote_bitbang_bitbang; - remote_bitbang_start = 0; - remote_bitbang_end = 0; + remote_bitbang_recv_buf_start = 0; + remote_bitbang_recv_buf_end = 0; LOG_INFO("Initializing remote_bitbang driver"); if (remote_bitbang_port == NULL) @@ -326,8 +360,23 @@ static const struct command_registration remote_bitbang_command_handlers[] = { COMMAND_REGISTRATION_DONE, }; +static int remote_bitbang_execute_queue(void) +{ + /* safety: the send buffer must be empty, no leftover characters from + * previous transactions */ + assert(remote_bitbang_send_buf_used == 0); + + /* process the JTAG command queue */ + int ret = bitbang_execute_queue(); + if (ret != ERROR_OK) + return ret; + + /* flush not-yet-sent characters, if any */ + return remote_bitbang_flush(); +} + static struct jtag_interface remote_bitbang_interface = { - .execute_queue = &bitbang_execute_queue, + .execute_queue = &remote_bitbang_execute_queue, }; struct adapter_driver remote_bitbang_adapter_driver = { From 64c2e03b23d9cadc1b919d38e902a079d015ddc6 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Fri, 23 Apr 2021 10:47:17 +0200 Subject: [PATCH 03/27] flash/nor: improved API of flash_driver.info & fixed buffer overruns 1) The API of "info" callback in "struct flash_driver" has been improved. Fixed buffers for strings 2) Removed the calls to snprintf() from the flash_driver.info implementations. Many of them were used in an unsafe manner (buffer overruns were possible). Change-Id: I42ab8a8018d01f9af43c5ba49f650c3cb5d31dcb Signed-off-by: Jan Matyas Reviewed-on: http://openocd.zylin.com/6182 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- src/flash/nor/ambiqmicro.c | 9 +--- src/flash/nor/at91sam3.c | 6 +-- src/flash/nor/at91sam4.c | 15 +++--- src/flash/nor/at91sam7.c | 33 ++++--------- src/flash/nor/ath79.c | 7 ++- src/flash/nor/atsamv.c | 4 +- src/flash/nor/avrf.c | 6 +-- src/flash/nor/bluenrg-x.c | 9 ++-- src/flash/nor/cc26xx.c | 8 +--- src/flash/nor/cc3220sf.c | 10 +--- src/flash/nor/cfi.c | 89 ++++++++++------------------------- src/flash/nor/cfi.h | 2 +- src/flash/nor/driver.h | 9 ++-- src/flash/nor/efm32.c | 33 +++---------- src/flash/nor/esirisc_flash.c | 4 +- src/flash/nor/faux.c | 4 +- src/flash/nor/fespi.c | 7 ++- src/flash/nor/fm4.c | 7 ++- src/flash/nor/jtagspi.c | 6 +-- src/flash/nor/kinetis.c | 4 +- src/flash/nor/kinetis_ke.c | 5 +- src/flash/nor/lpc2000.c | 6 +-- src/flash/nor/lpcspifi.c | 7 ++- src/flash/nor/max32xxx.c | 7 +-- src/flash/nor/mdr.c | 6 +-- src/flash/nor/mrvlqspi.c | 7 ++- src/flash/nor/msp432.c | 28 ++++------- src/flash/nor/niietcm4.c | 7 ++- src/flash/nor/nrf5.c | 53 ++++++++++++--------- src/flash/nor/pic32mx.c | 20 ++++---- src/flash/nor/psoc4.c | 17 +++---- src/flash/nor/psoc5lp.c | 12 ++--- src/flash/nor/psoc6.c | 4 +- src/flash/nor/sh_qspi.c | 7 ++- src/flash/nor/sim3x.c | 33 +++---------- src/flash/nor/stellaris.c | 62 +++++++++++------------- src/flash/nor/stm32f1x.c | 10 ++-- src/flash/nor/stm32f2x.c | 8 ++-- src/flash/nor/stm32h7x.c | 12 ++--- src/flash/nor/stm32l4x.c | 64 ++++++++++++++----------- src/flash/nor/stm32lx.c | 13 ++--- src/flash/nor/stmqspi.c | 7 ++- src/flash/nor/stmsmi.c | 7 ++- src/flash/nor/str7x.c | 4 +- src/flash/nor/tcl.c | 9 ++-- src/flash/nor/tms470.c | 14 ++---- src/flash/nor/virtual.c | 4 +- src/flash/nor/w600.c | 4 +- src/flash/nor/xcf.c | 6 +-- src/flash/nor/xmc1xxx.c | 5 +- src/flash/nor/xmc4xxx.c | 12 ++--- 51 files changed, 290 insertions(+), 442 deletions(-) diff --git a/src/flash/nor/ambiqmicro.c b/src/flash/nor/ambiqmicro.c index 1c4dce87d..c4c69ce2b 100644 --- a/src/flash/nor/ambiqmicro.c +++ b/src/flash/nor/ambiqmicro.c @@ -161,10 +161,9 @@ FLASH_BANK_COMMAND_HANDLER(ambiqmicro_flash_bank_command) return ERROR_OK; } -static int get_ambiqmicro_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_ambiqmicro_info(struct flash_bank *bank, struct command_invocation *cmd) { struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; - int printed; char *classname; if (!ambiqmicro_info->probed) { @@ -178,16 +177,12 @@ static int get_ambiqmicro_info(struct flash_bank *bank, char *buf, int buf_size) else classname = ambiqmicroClassname[0]; - printed = snprintf(buf, - buf_size, - "\nAmbiq Micro information: Chip is " + command_print_sameline(cmd, "\nAmbiq Micro information: Chip is " "class %d (%s) %s\n", ambiqmicro_info->target_class, classname, ambiqmicro_info->target_name); - if ((printed < 0)) - return ERROR_BUF_TOO_SMALL; return ERROR_OK; } diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index 9c4afd4af..e0c779a33 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -256,7 +256,7 @@ static struct sam3_chip *get_current_sam3(struct command_invocation *cmd) t = get_current_target(cmd->ctx); if (!t) { - command_print(cmd, "No current target?"); + command_print_sameline(cmd, "No current target?\n"); return NULL; } @@ -264,7 +264,7 @@ static struct sam3_chip *get_current_sam3(struct command_invocation *cmd) if (!p) { /* this should not happen */ /* the command is not registered until the chip is created? */ - command_print(cmd, "No SAM3 chips exist?"); + command_print_sameline(cmd, "No SAM3 chips exist?\n"); return NULL; } @@ -273,7 +273,7 @@ static struct sam3_chip *get_current_sam3(struct command_invocation *cmd) return p; p = p->next; } - command_print(cmd, "Cannot find SAM3 chip?"); + command_print_sameline(cmd, "Cannot find SAM3 chip?\n"); return NULL; } diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c index d4326e43a..b7ae7f691 100644 --- a/src/flash/nor/at91sam4.c +++ b/src/flash/nor/at91sam4.c @@ -235,7 +235,7 @@ static struct sam4_chip *get_current_sam4(struct command_invocation *cmd) t = get_current_target(cmd->ctx); if (!t) { - command_print(cmd, "No current target?"); + command_print_sameline(cmd, "No current target?\n"); return NULL; } @@ -243,7 +243,7 @@ static struct sam4_chip *get_current_sam4(struct command_invocation *cmd) if (!p) { /* this should not happen */ /* the command is not registered until the chip is created? */ - command_print(cmd, "No SAM4 chips exist?"); + command_print_sameline(cmd, "No SAM4 chips exist?\n"); return NULL; } @@ -252,7 +252,7 @@ static struct sam4_chip *get_current_sam4(struct command_invocation *cmd) return p; p = p->next; } - command_print(cmd, "Cannot find SAM4 chip?"); + command_print_sameline(cmd, "Cannot find SAM4 chip?\n"); return NULL; } @@ -2656,19 +2656,16 @@ static int sam4_GetDetails(struct sam4_bank_private *pPrivate) return ERROR_OK; } -static int sam4_info(struct flash_bank *bank, char *buf, int buf_size) +static int sam4_info(struct flash_bank *bank, struct command_invocation *cmd) { struct sam4_bank_private *pPrivate; int k = bank->size / 1024; pPrivate = get_sam4_bank_private(bank); - if (pPrivate == NULL) { - buf[0] = '\0'; + if (pPrivate == NULL) return ERROR_FAIL; - } - snprintf(buf, buf_size, - "%s bank %d: %d kB at " TARGET_ADDR_FMT, + command_print_sameline(cmd, "%s bank %d: %d kB at " TARGET_ADDR_FMT, pPrivate->pChip->details.name, pPrivate->bank_number, k, diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c index 3d8fee1af..88f489f60 100644 --- a/src/flash/nor/at91sam7.c +++ b/src/flash/nor/at91sam7.c @@ -978,23 +978,17 @@ static int at91sam7_probe(struct flash_bank *bank) return ERROR_OK; } -static int get_at91sam7_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_at91sam7_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv; if (at91sam7_info->cidr == 0) return ERROR_FLASH_BANK_NOT_PROBED; - printed = snprintf(buf, buf_size, - "\n at91sam7 driver information: Chip is %s\n", + command_print_sameline(cmd, "\n at91sam7 driver information: Chip is %s\n", at91sam7_info->target_name); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, - buf_size, + command_print_sameline(cmd, " Cidr: 0x%8.8" PRIx32 " | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | " "Flashsize: 0x%8.8" PRIx32 "\n", at91sam7_info->cidr, @@ -1003,31 +997,20 @@ static int get_at91sam7_info(struct flash_bank *bank, char *buf, int buf_size) at91sam7_info->cidr_version, bank->size); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, buf_size, - " Master clock (estimated): %u KHz | External clock: %u KHz\n", + command_print_sameline(cmd, + " Master clock (estimated): %u kHz | External clock: %u kHz\n", (unsigned)(at91sam7_info->mck_freq / 1000), (unsigned)(at91sam7_info->ext_freq / 1000)); - buf += printed; - buf_size -= printed; - - printed = snprintf(buf, - buf_size, + command_print_sameline(cmd, " Pagesize: %i bytes | Lockbits(%u): %i 0x%4.4x | Pages in lock region: %i\n", at91sam7_info->pagesize, bank->num_sectors, at91sam7_info->num_lockbits_on, at91sam7_info->lockbits, - at91sam7_info->pages_per_sector*at91sam7_info->num_lockbits_on); + at91sam7_info->pages_per_sector * at91sam7_info->num_lockbits_on); - buf += printed; - buf_size -= printed; - - snprintf(buf, buf_size, - " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n", + command_print_sameline(cmd, " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->num_nvmbits, at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits); diff --git a/src/flash/nor/ath79.c b/src/flash/nor/ath79.c index 9a4595f6d..394b6dda0 100644 --- a/src/flash/nor/ath79.c +++ b/src/flash/nor/ath79.c @@ -875,17 +875,16 @@ static int ath79_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int get_ath79_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_ath79_info(struct flash_bank *bank, struct command_invocation *cmd) { struct ath79_flash_bank *ath79_info = bank->driver_priv; if (!ath79_info->probed) { - snprintf(buf, buf_size, - "\nATH79 flash bank not probed yet\n"); + command_print_sameline(cmd, "\nATH79 flash bank not probed yet\n"); return ERROR_OK; } - snprintf(buf, buf_size, "\nATH79 flash information:\n" + command_print_sameline(cmd, "\nATH79 flash information:\n" " Device \'%s\' (ID 0x%08" PRIx32 ")\n", ath79_info->dev->name, ath79_info->dev->device_id); diff --git a/src/flash/nor/atsamv.c b/src/flash/nor/atsamv.c index 8f1450bf7..f70e5d010 100644 --- a/src/flash/nor/atsamv.c +++ b/src/flash/nor/atsamv.c @@ -607,7 +607,7 @@ static int samv_write(struct flash_bank *bank, const uint8_t *buffer, return ERROR_OK; } -static int samv_get_info(struct flash_bank *bank, char *buf, int buf_size) +static int samv_get_info(struct flash_bank *bank, struct command_invocation *cmd) { struct samv_flash_bank *samv_info = bank->driver_priv; if (!samv_info->probed) { @@ -615,7 +615,7 @@ static int samv_get_info(struct flash_bank *bank, char *buf, int buf_size) if (ERROR_OK != r) return r; } - snprintf(buf, buf_size, "Cortex-M7 detected with %" PRIu32 " kB flash", + command_print_sameline(cmd, "Cortex-M7 detected with %" PRIu32 " kB flash\n", bank->size / 1024); return ERROR_OK; } diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c index dd3d077a0..46621e99f 100644 --- a/src/flash/nor/avrf.c +++ b/src/flash/nor/avrf.c @@ -367,7 +367,7 @@ static int avrf_auto_probe(struct flash_bank *bank) return avrf_probe(bank); } -static int avrf_info(struct flash_bank *bank, char *buf, int buf_size) +static int avrf_info(struct flash_bank *bank, struct command_invocation *cmd) { struct target *target = bank->target; struct avr_common *avr = target->arch_info; @@ -400,12 +400,12 @@ static int avrf_info(struct flash_bank *bank, char *buf, int buf_size) if (avr_info != NULL) { /* chip found */ - snprintf(buf, buf_size, "%s - Rev: 0x%" PRIx32 "", avr_info->name, + command_print_sameline(cmd, "%s - Rev: 0x%" PRIx32 "", avr_info->name, EXTRACT_VER(device_id)); return ERROR_OK; } else { /* chip not supported */ - snprintf(buf, buf_size, "Cannot identify target as a avr\n"); + command_print_sameline(cmd, "Cannot identify target as a avr\n"); return ERROR_FLASH_OPERATION_FAILED; } } diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c index cf968cb8c..f533d54e9 100644 --- a/src/flash/nor/bluenrg-x.c +++ b/src/flash/nor/bluenrg-x.c @@ -429,7 +429,7 @@ static int bluenrgx_auto_probe(struct flash_bank *bank) } /* This method must return a string displaying information about the bank */ -static int bluenrgx_get_info(struct flash_bank *bank, char *buf, int buf_size) +static int bluenrgx_get_info(struct flash_bank *bank, struct command_invocation *cmd) { struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; int mask_number, cut_number; @@ -437,8 +437,7 @@ static int bluenrgx_get_info(struct flash_bank *bank, char *buf, int buf_size) if (!bluenrgx_info->probed) { int retval = bluenrgx_probe(bank); if (retval != ERROR_OK) { - snprintf(buf, buf_size, - "Unable to find bank information."); + command_print_sameline(cmd, "Unable to find bank information."); return retval; } } @@ -446,8 +445,8 @@ static int bluenrgx_get_info(struct flash_bank *bank, char *buf, int buf_size) mask_number = (bluenrgx_info->die_id >> 4) & 0xF; cut_number = bluenrgx_info->die_id & 0xF; - snprintf(buf, buf_size, - "%s - Rev: %d.%d", bluenrgx_info->flash_ptr->part_name, mask_number, cut_number); + command_print_sameline(cmd, "%s - Rev: %d.%d", + bluenrgx_info->flash_ptr->part_name, mask_number, cut_number); return ERROR_OK; } diff --git a/src/flash/nor/cc26xx.c b/src/flash/nor/cc26xx.c index 5565aeb41..4d58daad8 100644 --- a/src/flash/nor/cc26xx.c +++ b/src/flash/nor/cc26xx.c @@ -498,10 +498,9 @@ static int cc26xx_auto_probe(struct flash_bank *bank) return retval; } -static int cc26xx_info(struct flash_bank *bank, char *buf, int buf_size) +static int cc26xx_info(struct flash_bank *bank, struct command_invocation *cmd) { struct cc26xx_bank *cc26xx_bank = bank->driver_priv; - int printed = 0; const char *device; switch (cc26xx_bank->device_type) { @@ -526,13 +525,10 @@ static int cc26xx_info(struct flash_bank *bank, char *buf, int buf_size) break; } - printed = snprintf(buf, buf_size, + command_print_sameline(cmd, "%s device: ICEPick ID 0x%08" PRIx32 ", USER ID 0x%08" PRIx32 "\n", device, cc26xx_bank->icepick_id, cc26xx_bank->user_id); - if (printed >= buf_size) - return ERROR_BUF_TOO_SMALL; - return ERROR_OK; } diff --git a/src/flash/nor/cc3220sf.c b/src/flash/nor/cc3220sf.c index 5427bd3a9..1d01ba3be 100644 --- a/src/flash/nor/cc3220sf.c +++ b/src/flash/nor/cc3220sf.c @@ -477,15 +477,9 @@ static int cc3220sf_auto_probe(struct flash_bank *bank) return retval; } -static int cc3220sf_info(struct flash_bank *bank, char *buf, int buf_size) +static int cc3220sf_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; - - printed = snprintf(buf, buf_size, "CC3220SF with 1MB internal flash\n"); - - if (printed >= buf_size) - return ERROR_BUF_TOO_SMALL; - + command_print_sameline(cmd, "CC3220SF with 1MB internal flash\n"); return ERROR_OK; } diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index c9eb38b9b..666316932 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -728,79 +728,57 @@ static int cfi_read_0002_pri_ext(struct flash_bank *bank) return cfi_read_spansion_pri_ext(bank); } -static int cfi_spansion_info(struct flash_bank *bank, char *buf, int buf_size) +static int cfi_spansion_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - printed = snprintf(buf, buf_size, "\nSpansion primary algorithm extend information:\n"); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, "\nSpansion primary algorithm extend information:\n"); - printed = snprintf(buf, buf_size, "pri: '%c%c%c', version: %c.%c\n", pri_ext->pri[0], - pri_ext->pri[1], pri_ext->pri[2], + command_print_sameline(cmd, "pri: '%c%c%c', version: %c.%c\n", + pri_ext->pri[0], pri_ext->pri[1], pri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "Silicon Rev.: 0x%x, Address Sensitive unlock: 0x%x\n", + command_print_sameline(cmd, "Silicon Rev.: 0x%x, Address Sensitive unlock: 0x%x\n", (pri_ext->SiliconRevision) >> 2, (pri_ext->SiliconRevision) & 0x03); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "Erase Suspend: 0x%x, Sector Protect: 0x%x\n", + command_print_sameline(cmd, "Erase Suspend: 0x%x, Sector Protect: 0x%x\n", pri_ext->EraseSuspend, pri_ext->BlkProt); - buf += printed; - buf_size -= printed; - snprintf(buf, buf_size, "VppMin: %u.%x, VppMax: %u.%x\n", + command_print_sameline(cmd, "VppMin: %u.%x, VppMax: %u.%x\n", (pri_ext->VppMin & 0xf0) >> 4, pri_ext->VppMin & 0x0f, (pri_ext->VppMax & 0xf0) >> 4, pri_ext->VppMax & 0x0f); return ERROR_OK; } -static int cfi_intel_info(struct flash_bank *bank, char *buf, int buf_size) +static int cfi_intel_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext; - printed = snprintf(buf, buf_size, "\nintel primary algorithm extend information:\n"); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, "\nintel primary algorithm extend information:\n"); - printed = snprintf(buf, - buf_size, - "pri: '%c%c%c', version: %c.%c\n", + command_print_sameline(cmd, "pri: '%c%c%c', version: %c.%c\n", pri_ext->pri[0], pri_ext->pri[1], pri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, - buf_size, - "feature_support: 0x%" PRIx32 ", " + command_print_sameline(cmd, "feature_support: 0x%" PRIx32 ", " "suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x\n", pri_ext->feature_support, pri_ext->suspend_cmd_support, pri_ext->blk_status_reg_mask); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "Vcc opt: %x.%x, Vpp opt: %u.%x\n", + command_print_sameline(cmd, "Vcc opt: %x.%x, Vpp opt: %u.%x\n", (pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f, (pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f); - buf += printed; - buf_size -= printed; - snprintf(buf, buf_size, "protection_fields: %i, prot_reg_addr: 0x%x, " + command_print_sameline(cmd, "protection_fields: %i, prot_reg_addr: 0x%x, " "factory pre-programmed: %i, user programmable: %i\n", pri_ext->num_protection_fields, pri_ext->prot_reg_addr, 1 << pri_ext->fact_prot_reg_size, 1 << pri_ext->user_prot_reg_size); @@ -2992,45 +2970,36 @@ int cfi_protect_check(struct flash_bank *bank) return ERROR_OK; } -int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) +int cfi_get_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct cfi_flash_bank *cfi_info = bank->driver_priv; if (cfi_info->qry[0] == 0xff) { - snprintf(buf, buf_size, "\ncfi flash bank not probed yet\n"); + command_print_sameline(cmd, "\ncfi flash bank not probed yet\n"); return ERROR_OK; } if (!cfi_info->not_cfi) - printed = snprintf(buf, buf_size, "\nCFI flash: "); + command_print_sameline(cmd, "\nCFI flash: "); else - printed = snprintf(buf, buf_size, "\nnon-CFI flash: "); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, "\nnon-CFI flash: "); - printed = snprintf(buf, buf_size, "mfr: 0x%4.4x, id:0x%4.4x\n\n", + command_print_sameline(cmd, "mfr: 0x%4.4x, id:0x%4.4x\n", cfi_info->manufacturer, cfi_info->device_id); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: " + command_print_sameline(cmd, "qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: " "0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x\n", cfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2], cfi_info->pri_id, cfi_info->pri_addr, cfi_info->alt_id, cfi_info->alt_addr); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "Vcc min: %x.%x, Vcc max: %x.%x, " + command_print_sameline(cmd, "Vcc min: %x.%x, Vcc max: %x.%x, " "Vpp min: %u.%x, Vpp max: %u.%x\n", (cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f, (cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f, (cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f, (cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "typ. word write timeout: %u us, " + command_print_sameline(cmd, "typ. word write timeout: %u us, " "typ. buf write timeout: %u us, " "typ. block erase timeout: %u ms, " "typ. chip erase timeout: %u ms\n", @@ -3038,12 +3007,8 @@ int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) 1 << cfi_info->buf_write_timeout_typ, 1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, - buf_size, - "max. word write timeout: %u us, " + command_print_sameline(cmd, "max. word write timeout: %u us, " "max. buf write timeout: %u us, max. " "block erase timeout: %u ms, max. chip erase timeout: %u ms\n", (1 << @@ -3056,24 +3021,20 @@ int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) (1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ)); - buf += printed; - buf_size -= printed; - printed = snprintf(buf, buf_size, "size: 0x%" PRIx32 ", interface desc: %i, " + command_print_sameline(cmd, "size: 0x%" PRIx32 ", interface desc: %i, " "max buffer write size: 0x%x\n", cfi_info->dev_size, cfi_info->interface_desc, 1 << cfi_info->max_buf_write_size); - buf += printed; - buf_size -= printed; switch (cfi_info->pri_id) { case 1: case 3: - cfi_intel_info(bank, buf, buf_size); + cfi_intel_info(bank, cmd); break; case 2: - cfi_spansion_info(bank, buf, buf_size); + cfi_spansion_info(bank, cmd); break; default: LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); diff --git a/src/flash/nor/cfi.h b/src/flash/nor/cfi.h index eceb9a4b3..80633f494 100644 --- a/src/flash/nor/cfi.h +++ b/src/flash/nor/cfi.h @@ -160,7 +160,7 @@ int cfi_protect(struct flash_bank *bank, int set, unsigned int first, int cfi_probe(struct flash_bank *bank); int cfi_auto_probe(struct flash_bank *bank); int cfi_protect_check(struct flash_bank *bank); -int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size); +int cfi_get_info(struct flash_bank *bank, struct command_invocation *cmd); int cfi_flash_bank_cmd(struct flash_bank *bank, unsigned int argc, const char **argv); uint32_t cfi_flash_address(struct flash_bank *bank, int sector, uint32_t offset); diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index e29d4f528..7a5be6517 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -205,15 +205,14 @@ struct flash_driver { /** * Display human-readable information about the flash - * bank into the given buffer. Drivers must be careful to avoid - * overflowing the buffer. + * bank. * * @param bank - the bank to get info about - * @param char - where to put the text for the human to read - * @param buf_size - the size of the human buffer. + * @param cmd - command invocation instance for which to generate + * the textual output * @returns ERROR_OK if successful; otherwise, an error code. */ - int (*info)(struct flash_bank *bank, char *buf, int buf_size); + int (*info)(struct flash_bank *bank, struct command_invocation *cmd); /** * A more gentle flavor of flash_driver_s::probe, performing diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c index 6f2900762..6461e4c72 100644 --- a/src/flash/nor/efm32.c +++ b/src/flash/nor/efm32.c @@ -324,23 +324,7 @@ static int efm32x_read_info(struct flash_bank *bank, return ERROR_OK; } -/* - * Helper to create a human friendly string describing a part - */ -static int efm32x_decode_info(struct efm32_info *info, char *buf, int buf_size) -{ - int printed = 0; - printed = snprintf(buf, buf_size, "%s Gecko, rev %d", - info->family_data->name, info->prod_rev); - - if (printed >= buf_size) - return ERROR_BUF_TOO_SMALL; - - return ERROR_OK; -} - -/* flash bank efm32 0 0 - */ +/* flash bank efm32 0 0 */ FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command) { struct efm32x_flash_bank *efm32x_info; @@ -961,7 +945,6 @@ static int efm32x_probe(struct flash_bank *bank) struct efm32_info efm32_mcu_info; int ret; uint32_t base_address = 0x00000000; - char buf[256]; efm32x_info->probed = false; memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ); @@ -970,11 +953,8 @@ static int efm32x_probe(struct flash_bank *bank) if (ERROR_OK != ret) return ret; - ret = efm32x_decode_info(&efm32_mcu_info, buf, sizeof(buf)); - if (ERROR_OK != ret) - return ret; - - LOG_INFO("detected part: %s", buf); + LOG_INFO("detected part: %s Gecko, rev %d", + efm32_mcu_info.family_data->name, efm32_mcu_info.prod_rev); LOG_INFO("flash size = %dkbytes", efm32_mcu_info.flash_sz_kib); LOG_INFO("flash page size = %dbytes", efm32_mcu_info.page_size); @@ -1044,10 +1024,10 @@ static int efm32x_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int get_efm32x_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_efm32x_info(struct flash_bank *bank, struct command_invocation *cmd) { struct efm32_info info; - int ret = 0; + int ret; ret = efm32x_read_info(bank, &info); if (ERROR_OK != ret) { @@ -1055,7 +1035,8 @@ static int get_efm32x_info(struct flash_bank *bank, char *buf, int buf_size) return ret; } - return efm32x_decode_info(&info, buf, buf_size); + command_print_sameline(cmd, "%s Gecko, rev %d", info.family_data->name, info.prod_rev); + return ERROR_OK; } COMMAND_HANDLER(efm32x_handle_debuglock_command) diff --git a/src/flash/nor/esirisc_flash.c b/src/flash/nor/esirisc_flash.c index 24e811704..23fd01e55 100644 --- a/src/flash/nor/esirisc_flash.c +++ b/src/flash/nor/esirisc_flash.c @@ -487,11 +487,11 @@ static int esirisc_flash_auto_probe(struct flash_bank *bank) return esirisc_flash_probe(bank); } -static int esirisc_flash_info(struct flash_bank *bank, char *buf, int buf_size) +static int esirisc_flash_info(struct flash_bank *bank, struct command_invocation *cmd) { struct esirisc_flash_bank *esirisc_info = bank->driver_priv; - snprintf(buf, buf_size, + command_print_sameline(cmd, "%4s cfg at 0x%" PRIx32 ", clock %" PRIu32 ", wait_states %" PRIu32, "", /* align with first line */ esirisc_info->cfg, diff --git a/src/flash/nor/faux.c b/src/flash/nor/faux.c index d6c6b2dae..ed278b424 100644 --- a/src/flash/nor/faux.c +++ b/src/flash/nor/faux.c @@ -92,9 +92,9 @@ static int faux_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t o return ERROR_OK; } -static int faux_info(struct flash_bank *bank, char *buf, int buf_size) +static int faux_info(struct flash_bank *bank, struct command_invocation *cmd) { - snprintf(buf, buf_size, "faux flash driver"); + command_print_sameline(cmd, "faux flash driver"); return ERROR_OK; } diff --git a/src/flash/nor/fespi.c b/src/flash/nor/fespi.c index 02630ac24..0a14c5092 100644 --- a/src/flash/nor/fespi.c +++ b/src/flash/nor/fespi.c @@ -1017,17 +1017,16 @@ static int fespi_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int get_fespi_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_fespi_info(struct flash_bank *bank, struct command_invocation *cmd) { struct fespi_flash_bank *fespi_info = bank->driver_priv; if (!(fespi_info->probed)) { - snprintf(buf, buf_size, - "\nFESPI flash bank not probed yet\n"); + command_print_sameline(cmd, "\nFESPI flash bank not probed yet\n"); return ERROR_OK; } - snprintf(buf, buf_size, "\nFESPI flash information:\n" + command_print_sameline(cmd, "\nFESPI flash information:\n" " Device \'%s\' (ID 0x%08" PRIx32 ")\n", fespi_info->dev->name, fespi_info->dev->device_id); diff --git a/src/flash/nor/fm4.c b/src/flash/nor/fm4.c index 211a00863..2c51e007f 100644 --- a/src/flash/nor/fm4.c +++ b/src/flash/nor/fm4.c @@ -539,7 +539,7 @@ static int fm4_auto_probe(struct flash_bank *bank) return fm4_probe(bank); } -static int fm4_get_info_command(struct flash_bank *bank, char *buf, int buf_size) +static int fm4_get_info_command(struct flash_bank *bank, struct command_invocation *cmd) { struct fm4_flash_bank *fm4_bank = bank->driver_priv; const char *name; @@ -586,11 +586,10 @@ static int fm4_get_info_command(struct flash_bank *bank, char *buf, int buf_size case s6e2cx8: case s6e2cx9: case s6e2cxa: - snprintf(buf, buf_size, "%s MainFlash Macro #%i", - name, fm4_bank->macro_nr); + command_print_sameline(cmd, "%s MainFlash Macro #%i", name, fm4_bank->macro_nr); break; default: - snprintf(buf, buf_size, "%s MainFlash", name); + command_print_sameline(cmd, "%s MainFlash", name); break; } diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index 20362f384..f40efe84f 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -421,16 +421,16 @@ static int jtagspi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_ return ERROR_OK; } -static int jtagspi_info(struct flash_bank *bank, char *buf, int buf_size) +static int jtagspi_info(struct flash_bank *bank, struct command_invocation *cmd) { struct jtagspi_flash_bank *info = bank->driver_priv; if (!(info->probed)) { - snprintf(buf, buf_size, "\nJTAGSPI flash bank not probed yet\n"); + command_print_sameline(cmd, "\nJTAGSPI flash bank not probed yet\n"); return ERROR_OK; } - snprintf(buf, buf_size, "\nSPIFI flash information:\n" + command_print_sameline(cmd, "\nSPIFI flash information:\n" " Device \'%s\' (ID 0x%08" PRIx32 ")\n", info->dev->name, info->dev->device_id); diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index 1fee6eb2e..45046d607 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -2778,7 +2778,7 @@ static int kinetis_auto_probe(struct flash_bank *bank) return kinetis_probe(bank); } -static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size) +static int kinetis_info(struct flash_bank *bank, struct command_invocation *cmd) { const char *bank_class_names[] = { "(ANY)", "PFlash", "FlexNVM", "FlexRAM" @@ -2788,7 +2788,7 @@ static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size) struct kinetis_chip *k_chip = k_bank->k_chip; uint32_t size_k = bank->size / 1024; - snprintf(buf, buf_size, + command_print_sameline(cmd, "%s %s: %" PRIu32 "k %s bank %s at " TARGET_ADDR_FMT, bank->driver->name, k_chip->name, size_k, bank_class_names[k_bank->flash_class], diff --git a/src/flash/nor/kinetis_ke.c b/src/flash/nor/kinetis_ke.c index 5aba7fc64..0d094b5f9 100644 --- a/src/flash/nor/kinetis_ke.c +++ b/src/flash/nor/kinetis_ke.c @@ -1171,10 +1171,9 @@ static int kinetis_ke_auto_probe(struct flash_bank *bank) return kinetis_ke_probe(bank); } -static int kinetis_ke_info(struct flash_bank *bank, char *buf, int buf_size) +static int kinetis_ke_info(struct flash_bank *bank, struct command_invocation *cmd) { - (void) snprintf(buf, buf_size, - "%s driver for flash bank %s at " TARGET_ADDR_FMT, + command_print_sameline(cmd, "%s driver for flash bank %s at " TARGET_ADDR_FMT, bank->driver->name, bank->name, bank->base); return ERROR_OK; diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c index 3ad62d669..09b5c6aec 100644 --- a/src/flash/nor/lpc2000.c +++ b/src/flash/nor/lpc2000.c @@ -1552,12 +1552,12 @@ static int lpc2000_erase_check(struct flash_bank *bank) return lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1); } -static int get_lpc2000_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_lpc2000_info(struct flash_bank *bank, struct command_invocation *cmd) { struct lpc2000_flash_bank *lpc2000_info = bank->driver_priv; - snprintf(buf, buf_size, "lpc2000 flash driver variant: %i, clk: %" PRIu32 "kHz", lpc2000_info->variant, - lpc2000_info->cclk); + command_print_sameline(cmd, "lpc2000 flash driver variant: %i, clk: %" PRIu32 "kHz", + lpc2000_info->variant, lpc2000_info->cclk); return ERROR_OK; } diff --git a/src/flash/nor/lpcspifi.c b/src/flash/nor/lpcspifi.c index dd1c63d74..c99ce8d4c 100644 --- a/src/flash/nor/lpcspifi.c +++ b/src/flash/nor/lpcspifi.c @@ -926,17 +926,16 @@ static int lpcspifi_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int get_lpcspifi_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_lpcspifi_info(struct flash_bank *bank, struct command_invocation *cmd) { struct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv; if (!(lpcspifi_info->probed)) { - snprintf(buf, buf_size, - "\nSPIFI flash bank not probed yet\n"); + command_print_sameline(cmd, "\nSPIFI flash bank not probed yet\n"); return ERROR_OK; } - snprintf(buf, buf_size, "\nSPIFI flash information:\n" + command_print_sameline(cmd, "\nSPIFI flash information:\n" " Device \'%s\' (ID 0x%08" PRIx32 ")\n", lpcspifi_info->dev->name, lpcspifi_info->dev->device_id); diff --git a/src/flash/nor/max32xxx.c b/src/flash/nor/max32xxx.c index 586a73b1d..33d786889 100644 --- a/src/flash/nor/max32xxx.c +++ b/src/flash/nor/max32xxx.c @@ -113,17 +113,14 @@ FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command) return ERROR_OK; } -static int get_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct max32xxx_flash_bank *info = bank->driver_priv; if (!info->probed) return ERROR_FLASH_BANK_NOT_PROBED; - printed = snprintf(buf, buf_size, "\nMaxim Integrated max32xxx flash driver\n"); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, "\nMaxim Integrated max32xxx flash driver\n"); return ERROR_OK; } diff --git a/src/flash/nor/mdr.c b/src/flash/nor/mdr.c index 2518c229b..e8484199a 100644 --- a/src/flash/nor/mdr.c +++ b/src/flash/nor/mdr.c @@ -597,11 +597,11 @@ static int mdr_auto_probe(struct flash_bank *bank) return mdr_probe(bank); } -static int get_mdr_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_mdr_info(struct flash_bank *bank, struct command_invocation *cmd) { struct mdr_flash_bank *mdr_info = bank->driver_priv; - snprintf(buf, buf_size, "MDR32Fx - %s", - mdr_info->mem_type ? "info memory" : "main memory"); + command_print_sameline(cmd, "MDR32Fx - %s", + mdr_info->mem_type ? "info memory" : "main memory"); return ERROR_OK; } diff --git a/src/flash/nor/mrvlqspi.c b/src/flash/nor/mrvlqspi.c index b98c49dbc..44de98907 100644 --- a/src/flash/nor/mrvlqspi.c +++ b/src/flash/nor/mrvlqspi.c @@ -914,17 +914,16 @@ static int mrvlqspi_flash_erase_check(struct flash_bank *bank) return ERROR_OK; } -static int mrvlqspi_get_info(struct flash_bank *bank, char *buf, int buf_size) +static int mrvlqspi_get_info(struct flash_bank *bank, struct command_invocation *cmd) { struct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv; if (!(mrvlqspi_info->probed)) { - snprintf(buf, buf_size, - "\nQSPI flash bank not probed yet\n"); + command_print_sameline(cmd, "\nQSPI flash bank not probed yet\n"); return ERROR_OK; } - snprintf(buf, buf_size, "\nQSPI flash information:\n" + command_print_sameline(cmd, "\nQSPI flash information:\n" " Device \'%s\' ID 0x%08" PRIx32 "\n", mrvlqspi_info->dev->name, mrvlqspi_info->dev->device_id); diff --git a/src/flash/nor/msp432.c b/src/flash/nor/msp432.c index b6933e1e9..22f7c77a2 100644 --- a/src/flash/nor/msp432.c +++ b/src/flash/nor/msp432.c @@ -975,60 +975,50 @@ static int msp432_auto_probe(struct flash_bank *bank) return retval; } -static int msp432_info(struct flash_bank *bank, char *buf, int buf_size) +static int msp432_info(struct flash_bank *bank, struct command_invocation *cmd) { struct msp432_bank *msp432_bank = bank->driver_priv; - int printed = 0; switch (msp432_bank->device_type) { case MSP432P401X_DEPR: if (0xFFFF == msp432_bank->device_id) { /* Very early pre-production silicon currently deprecated */ - printed = snprintf(buf, buf_size, - "MSP432P401x pre-production device (deprecated silicon)\n" + command_print_sameline(cmd, "MSP432P401x pre-production device (deprecated silicon)\n" SUPPORT_MESSAGE); } else { /* Revision A or B silicon, also deprecated */ - printed = snprintf(buf, buf_size, - "MSP432P401x Device Rev %c (deprecated silicon)\n" + command_print_sameline(cmd, "MSP432P401x Device Rev %c (deprecated silicon)\n" SUPPORT_MESSAGE, (char)msp432_bank->hardware_rev); } break; case MSP432P401X: - printed = snprintf(buf, buf_size, - "MSP432P401x Device Rev %c\n", + command_print_sameline(cmd, "MSP432P401x Device Rev %c\n", (char)msp432_bank->hardware_rev); break; case MSP432P411X: - printed = snprintf(buf, buf_size, - "MSP432P411x Device Rev %c\n", + command_print_sameline(cmd, "MSP432P411x Device Rev %c\n", (char)msp432_bank->hardware_rev); break; case MSP432E401Y: - printed = snprintf(buf, buf_size, "MSP432E401Y Device\n"); + command_print_sameline(cmd, "MSP432E401Y Device\n"); break; case MSP432E411Y: - printed = snprintf(buf, buf_size, "MSP432E411Y Device\n"); + command_print_sameline(cmd, "MSP432E411Y Device\n"); break; case MSP432E4X_GUESS: - printed = snprintf(buf, buf_size, + command_print_sameline(cmd, "Unrecognized MSP432E4 DID0 and DID1 IDs (%08" PRIX32 ", %08" PRIX32 ")", msp432_bank->device_id, msp432_bank->hardware_rev); break; case MSP432P401X_GUESS: case MSP432P411X_GUESS: default: - printed = snprintf(buf, buf_size, + command_print_sameline(cmd, "Unrecognized MSP432P4 Device ID and Hardware Rev (%04" PRIX32 ", %02" PRIX32 ")", msp432_bank->device_id, msp432_bank->hardware_rev); break; } - buf_size -= printed; - - if (0 > buf_size) - return ERROR_BUF_TOO_SMALL; - return ERROR_OK; } diff --git a/src/flash/nor/niietcm4.c b/src/flash/nor/niietcm4.c index 1831314dd..d48569423 100644 --- a/src/flash/nor/niietcm4.c +++ b/src/flash/nor/niietcm4.c @@ -1719,12 +1719,11 @@ static int niietcm4_auto_probe(struct flash_bank *bank) return niietcm4_probe(bank); } -static int get_niietcm4_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_niietcm4_info(struct flash_bank *bank, struct command_invocation *cmd) { struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv; - LOG_INFO("\nNIIET Cortex-M4F %s\n%s", niietcm4_info->chip_name, niietcm4_info->chip_brief); - snprintf(buf, buf_size, " "); - + command_print_sameline(cmd, "\nNIIET Cortex-M4F %s\n%s", + niietcm4_info->chip_name, niietcm4_info->chip_brief); return ERROR_OK; } diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 5e17a8c7b..9decbea9d 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -624,35 +624,42 @@ static const char *nrf5_decode_info_package(uint32_t package) return "xx"; } -static int nrf5_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_nrf5_chip_type_str(const struct nrf5_info *chip, char *buf, unsigned int buf_size) { - struct nrf5_bank *nbank = bank->driver_priv; - struct nrf5_info *chip = nbank->chip; int res; - if (chip->spec) { - res = snprintf(buf, buf_size, - "nRF%s-%s(build code: %s)", + res = snprintf(buf, buf_size, "nRF%s-%s(build code: %s)", chip->spec->part, chip->spec->variant, chip->spec->build_code); - } else if (chip->ficr_info_valid) { char variant[5]; nrf5_info_variant_to_str(chip->ficr_info.variant, variant); - res = snprintf(buf, buf_size, - "nRF%" PRIx32 "-%s%.2s(build code: %s)", + res = snprintf(buf, buf_size, "nRF%" PRIx32 "-%s%.2s(build code: %s)", chip->ficr_info.part, nrf5_decode_info_package(chip->ficr_info.package), variant, &variant[2]); - } else { - res = snprintf(buf, buf_size, "nRF51xxx (HWID 0x%04" PRIx16 ")", - chip->hwid); + res = snprintf(buf, buf_size, "nRF51xxx (HWID 0x%04" PRIx16 ")", chip->hwid); } - if (res <= 0) + + /* safety: */ + if (res <= 0 || (unsigned int)res >= buf_size) { + LOG_ERROR("BUG: buffer problem in %s", __func__); + return ERROR_FAIL; + } + return ERROR_OK; +} + +static int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd) +{ + struct nrf5_bank *nbank = bank->driver_priv; + struct nrf5_info *chip = nbank->chip; + + char chip_type_str[256]; + if (get_nrf5_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK) return ERROR_FAIL; - snprintf(buf + res, buf_size - res, " %ukB Flash, %ukB RAM", - chip->flash_size_kb, chip->ram_size_kb); + command_print_sameline(cmd, "%s %ukB Flash, %ukB RAM", + chip_type_str, chip->flash_size_kb, chip->ram_size_kb); return ERROR_OK; } @@ -824,13 +831,15 @@ static int nrf5_probe(struct flash_bank *bank) chip->flash_size_kb = num_sectors * flash_page_size / 1024; if (!chip->bank[0].probed && !chip->bank[1].probed) { - char buf[80]; - nrf5_info(bank, buf, sizeof(buf)); - if (!chip->spec && !chip->ficr_info_valid) { - LOG_INFO("Unknown device: %s", buf); - } else { - LOG_INFO("%s", buf); - } + char chip_type_str[256]; + if (get_nrf5_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK) + return ERROR_FAIL; + const bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid); + LOG_INFO("%s%s %ukB Flash, %ukB RAM", + device_is_unknown ? "Unknown device: " : "", + chip_type_str, + chip->flash_size_kb, + chip->ram_size_kb); } free(bank->sectors); diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c index c42cfb2bb..6844975e2 100644 --- a/src/flash/nor/pic32mx.c +++ b/src/flash/nor/pic32mx.c @@ -801,37 +801,35 @@ static int pic32mx_auto_probe(struct flash_bank *bank) return pic32mx_probe(bank); } -static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size) +static int pic32mx_info(struct flash_bank *bank, struct command_invocation *cmd) { struct target *target = bank->target; struct mips32_common *mips32 = target->arch_info; struct mips_ejtag *ejtag_info = &mips32->ejtag_info; uint32_t device_id; - int printed = 0, i; device_id = ejtag_info->idcode; if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) { - snprintf(buf, buf_size, - "Cannot identify target as a PIC32MX family (manufacturer 0x%03x != 0x%03x)\n", - (unsigned)((device_id >> 1) & 0x7ff), - PIC32MX_MANUF_ID); + command_print_sameline(cmd, + "Cannot identify target as a PIC32MX family (manufacturer 0x%03x != 0x%03x)\n", + (unsigned)((device_id >> 1) & 0x7ff), + PIC32MX_MANUF_ID); return ERROR_FLASH_OPERATION_FAILED; } + int i; for (i = 0; pic32mx_devs[i].name != NULL; i++) { if (pic32mx_devs[i].devid == (device_id & 0x0fffffff)) { - printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name); + command_print_sameline(cmd, "PIC32MX%s", pic32mx_devs[i].name); break; } } if (pic32mx_devs[i].name == NULL) - printed = snprintf(buf, buf_size, "Unknown"); + command_print_sameline(cmd, "Unknown"); - buf += printed; - buf_size -= printed; - snprintf(buf, buf_size, " Ver: 0x%02x", + command_print_sameline(cmd, " Ver: 0x%02x", (unsigned)((device_id >> 28) & 0xf)); return ERROR_OK; diff --git a/src/flash/nor/psoc4.c b/src/flash/nor/psoc4.c index 3ca1f369c..cc2521b0d 100644 --- a/src/flash/nor/psoc4.c +++ b/src/flash/nor/psoc4.c @@ -851,7 +851,7 @@ static int psoc4_auto_probe(struct flash_bank *bank) } -static int get_psoc4_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_psoc4_info(struct flash_bank *bank, struct command_invocation *cmd) { struct target *target = bank->target; struct psoc4_flash_bank *psoc4_info = bank->driver_priv; @@ -863,35 +863,30 @@ static int get_psoc4_info(struct flash_bank *bank, char *buf, int buf_size) uint32_t size_in_kb = bank->size / 1024; if (target->state != TARGET_HALTED) { - snprintf(buf, buf_size, "%s, flash %" PRIu32 " kb" + command_print_sameline(cmd, "%s, flash %" PRIu32 " kb" " (halt target to see details)", family->name, size_in_kb); return ERROR_OK; } - int retval; - int printed = 0; uint32_t silicon_id; uint16_t family_id; uint8_t protection; - retval = psoc4_get_silicon_id(bank, &silicon_id, &family_id, &protection); + int retval = psoc4_get_silicon_id(bank, &silicon_id, &family_id, &protection); if (retval != ERROR_OK) return retval; if (family_id != psoc4_info->family_id) - printed = snprintf(buf, buf_size, "Family id mismatch 0x%02" PRIx16 + command_print_sameline(cmd, "Family id mismatch 0x%02" PRIx16 "/0x%02" PRIx16 ", silicon id 0x%08" PRIx32, psoc4_info->family_id, family_id, silicon_id); else { - printed = snprintf(buf, buf_size, "%s silicon id 0x%08" PRIx32 "", + command_print_sameline(cmd, "%s silicon id 0x%08" PRIx32 "", family->name, silicon_id); } - buf += printed; - buf_size -= printed; - const char *prot_txt = psoc4_decode_chip_protection(protection); - snprintf(buf, buf_size, ", flash %" PRIu32 " kb %s", size_in_kb, prot_txt); + command_print_sameline(cmd, ", flash %" PRIu32 " kb %s", size_in_kb, prot_txt); return ERROR_OK; } diff --git a/src/flash/nor/psoc5lp.c b/src/flash/nor/psoc5lp.c index c651dea7a..1b268b53d 100644 --- a/src/flash/nor/psoc5lp.c +++ b/src/flash/nor/psoc5lp.c @@ -753,14 +753,14 @@ static int psoc5lp_nvl_write(struct flash_bank *bank, } static int psoc5lp_nvl_get_info_command(struct flash_bank *bank, - char *buf, int buf_size) + struct command_invocation *cmd) { struct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv; char part_number[PART_NUMBER_LEN]; psoc5lp_get_part_number(psoc_nvl_bank->device, part_number); - snprintf(buf, buf_size, "%s", part_number); + command_print_sameline(cmd, "%s", part_number); return ERROR_OK; } @@ -934,14 +934,14 @@ static int psoc5lp_eeprom_write(struct flash_bank *bank, return ERROR_OK; } -static int psoc5lp_eeprom_get_info_command(struct flash_bank *bank, char *buf, int buf_size) +static int psoc5lp_eeprom_get_info_command(struct flash_bank *bank, struct command_invocation *cmd) { struct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv; char part_number[PART_NUMBER_LEN]; psoc5lp_get_part_number(psoc_eeprom_bank->device, part_number); - snprintf(buf, buf_size, "%s", part_number); + command_print_sameline(cmd, "%s", part_number); return ERROR_OK; } @@ -1397,7 +1397,7 @@ static int psoc5lp_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int psoc5lp_get_info_command(struct flash_bank *bank, char *buf, int buf_size) +static int psoc5lp_get_info_command(struct flash_bank *bank, struct command_invocation *cmd) { struct psoc5lp_flash_bank *psoc_bank = bank->driver_priv; char part_number[PART_NUMBER_LEN]; @@ -1406,7 +1406,7 @@ static int psoc5lp_get_info_command(struct flash_bank *bank, char *buf, int buf_ psoc5lp_get_part_number(psoc_bank->device, part_number); ecc = psoc_bank->ecc_enabled ? "ECC enabled" : "ECC disabled"; - snprintf(buf, buf_size, "%s %s", part_number, ecc); + command_print_sameline(cmd, "%s %s", part_number, ecc); return ERROR_OK; } diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c index 9c834fde6..c65411bb9 100644 --- a/src/flash/nor/psoc6.c +++ b/src/flash/nor/psoc6.c @@ -495,7 +495,7 @@ static const char *protection_to_str(uint8_t protection) * @param buf_size size of the buffer * @return ERROR_OK in case of success, ERROR_XXX code otherwise *************************************************************************************************/ -static int psoc6_get_info(struct flash_bank *bank, char *buf, int buf_size) +static int psoc6_get_info(struct flash_bank *bank, struct command_invocation *cmd) { struct psoc6_target_info *psoc6_info = bank->driver_priv; @@ -506,7 +506,7 @@ static int psoc6_get_info(struct flash_bank *bank, char *buf, int buf_size) if (hr != ERROR_OK) return hr; - snprintf(buf, buf_size, + command_print_sameline(cmd, "PSoC6 Silicon ID: 0x%08" PRIX32 "\n" "Protection: %s\n" "Main Flash size: %" PRIu32 " kB\n" diff --git a/src/flash/nor/sh_qspi.c b/src/flash/nor/sh_qspi.c index 4ec7ebe65..a1598449c 100644 --- a/src/flash/nor/sh_qspi.c +++ b/src/flash/nor/sh_qspi.c @@ -851,17 +851,16 @@ static int sh_qspi_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int sh_qspi_get_info(struct flash_bank *bank, char *buf, int buf_size) +static int sh_qspi_get_info(struct flash_bank *bank, struct command_invocation *cmd) { struct sh_qspi_flash_bank *info = bank->driver_priv; if (!info->probed) { - snprintf(buf, buf_size, - "\nSH QSPI flash bank not probed yet\n"); + command_print_sameline(cmd, "\nSH QSPI flash bank not probed yet\n"); return ERROR_OK; } - snprintf(buf, buf_size, "\nSH QSPI flash information:\n" + command_print_sameline(cmd, "\nSH QSPI flash information:\n" " Device \'%s\' (ID 0x%08" PRIx32 ")\n", info->dev->name, info->dev->device_id); diff --git a/src/flash/nor/sim3x.c b/src/flash/nor/sim3x.c index 76280f1ab..b42add96e 100644 --- a/src/flash/nor/sim3x.c +++ b/src/flash/nor/sim3x.c @@ -834,53 +834,32 @@ static int sim3x_auto_probe(struct flash_bank *bank) } } -static int sim3x_flash_info(struct flash_bank *bank, char *buf, int buf_size) +static int sim3x_flash_info(struct flash_bank *bank, struct command_invocation *cmd) { - int ret; - int printed = 0; struct sim3x_info *sim3x_info; sim3x_info = bank->driver_priv; /* Read info about chip */ - ret = sim3x_read_info(bank); + int ret = sim3x_read_info(bank); if (ret != ERROR_OK) return ret; /* Part */ if (sim3x_info->part_family && sim3x_info->part_number) { - printed = snprintf(buf, buf_size, "SiM3%c%d", sim3x_info->part_family, sim3x_info->part_number); - buf += printed; - buf_size -= printed; - - if (buf_size <= 0) - return ERROR_BUF_TOO_SMALL; + command_print_sameline(cmd, "SiM3%c%d", sim3x_info->part_family, sim3x_info->part_number); /* Revision */ if (sim3x_info->device_revision && sim3x_info->device_revision <= 'Z' - 'A') { - printed = snprintf(buf, buf_size, "-%c", sim3x_info->device_revision + 'A'); - buf += printed; - buf_size -= printed; - - if (buf_size <= 0) - return ERROR_BUF_TOO_SMALL; + command_print_sameline(cmd, "-%c", sim3x_info->device_revision + 'A'); /* Package */ - printed = snprintf(buf, buf_size, "-G%s", sim3x_info->device_package); - buf += printed; - buf_size -= printed; - - if (buf_size <= 0) - return ERROR_BUF_TOO_SMALL; + command_print_sameline(cmd, "-G%s", sim3x_info->device_package); } } /* Print flash size */ - printed = snprintf(buf, buf_size, " flash_size = %dKB", sim3x_info->flash_size_kb); - buf_size -= printed; - - if (buf_size <= 0) - return ERROR_BUF_TOO_SMALL; + command_print_sameline(cmd, " flash_size = %dKB", sim3x_info->flash_size_kb); return ERROR_OK; } diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index 55b99de3f..b4c959f05 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -479,9 +479,8 @@ FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command) return ERROR_OK; } -static int get_stellaris_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_stellaris_info(struct flash_bank *bank, struct command_invocation *cmd) { - int printed; struct stellaris_flash_bank *stellaris_info = bank->driver_priv; if (stellaris_info->did1 == 0) @@ -490,41 +489,34 @@ static int get_stellaris_info(struct flash_bank *bank, char *buf, int buf_size) /* Read main and master clock frequency register */ stellaris_read_clock_info(bank); - printed = snprintf(buf, - buf_size, - "\nTI/LMI Stellaris information: Chip is " - "class %i (%s) %s rev %c%i\n", - stellaris_info->target_class, - StellarisClassname[stellaris_info->target_class], - stellaris_info->target_name, - (int)('A' + ((stellaris_info->did0 >> 8) & 0xFF)), - (int)((stellaris_info->did0) & 0xFF)); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, + "\nTI/LMI Stellaris information: Chip is " + "class %i (%s) %s rev %c%i\n", + stellaris_info->target_class, + StellarisClassname[stellaris_info->target_class], + stellaris_info->target_name, + (int)('A' + ((stellaris_info->did0 >> 8) & 0xFF)), + (int)((stellaris_info->did0) & 0xFF)); - printed = snprintf(buf, - buf_size, - "did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32 - ", eproc: %s, ramsize: %" PRIu32 "k, flashsize: %" PRIu32 "k\n", - stellaris_info->did1, - stellaris_info->did1, - "ARMv7M", - stellaris_info->sramsiz, - (uint32_t)(stellaris_info->num_pages * stellaris_info->pagesize / 1024)); - buf += printed; - buf_size -= printed; + command_print_sameline(cmd, + "did1: 0x%8.8" PRIx32 ", arch: 0x%4.4" PRIx32 + ", eproc: %s, ramsize: %" PRIu32 "k, flashsize: %" PRIu32 "k\n", + stellaris_info->did1, + stellaris_info->did1, + "ARMv7M", + stellaris_info->sramsiz, + (uint32_t)(stellaris_info->num_pages * stellaris_info->pagesize / 1024)); - snprintf(buf, - buf_size, - "master clock: %ikHz%s, " - "rcc is 0x%" PRIx32 ", rcc2 is 0x%" PRIx32 ", " - "pagesize: %" PRIu32 ", pages: %" PRIu32, - (int)(stellaris_info->mck_freq / 1000), - stellaris_info->mck_desc, - stellaris_info->rcc, - stellaris_info->rcc2, - stellaris_info->pagesize, - stellaris_info->num_pages); + command_print_sameline(cmd, + "master clock: %ikHz%s, " + "rcc is 0x%" PRIx32 ", rcc2 is 0x%" PRIx32 ", " + "pagesize: %" PRIu32 ", pages: %" PRIu32, + (int)(stellaris_info->mck_freq / 1000), + stellaris_info->mck_desc, + stellaris_info->rcc, + stellaris_info->rcc2, + stellaris_info->pagesize, + stellaris_info->num_pages); return ERROR_OK; } diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 125f77691..91f2aef86 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -954,11 +954,11 @@ static const char *get_stm32f0_revision(uint16_t rev_id) return rev_str; } -static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_stm32x_info(struct flash_bank *bank, struct command_invocation *cmd) { uint32_t dbgmcu_idcode; - /* read stm32 device id register */ + /* read stm32 device id register */ int retval = stm32x_get_device_id(bank, &dbgmcu_idcode); if (retval != ERROR_OK) return retval; @@ -1174,14 +1174,14 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size) break; default: - snprintf(buf, buf_size, "Cannot identify target as a STM32F0/1/3\n"); + command_print_sameline(cmd, "Cannot identify target as a STM32F0/1/3\n"); return ERROR_FAIL; } if (rev_str != NULL) - snprintf(buf, buf_size, "%s - Rev: %s", device_str, rev_str); + command_print_sameline(cmd, "%s - Rev: %s", device_str, rev_str); else - snprintf(buf, buf_size, "%s - Rev: unknown (0x%04x)", device_str, rev_id); + command_print_sameline(cmd, "%s - Rev: unknown (0x%04x)", device_str, rev_id); return ERROR_OK; } diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c index e3625f322..44f06f4fd 100644 --- a/src/flash/nor/stm32f2x.c +++ b/src/flash/nor/stm32f2x.c @@ -1251,7 +1251,7 @@ static int stm32x_auto_probe(struct flash_bank *bank) return stm32x_probe(bank); } -static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_stm32x_info(struct flash_bank *bank, struct command_invocation *cmd) { uint32_t dbgmcu_idcode; @@ -1416,14 +1416,14 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size) break; default: - snprintf(buf, buf_size, "Cannot identify target as a STM32F2/4/7\n"); + command_print_sameline(cmd, "Cannot identify target as a STM32F2/4/7\n"); return ERROR_FAIL; } if (rev_str != NULL) - snprintf(buf, buf_size, "%s - Rev: %s", device_str, rev_str); + command_print_sameline(cmd, "%s - Rev: %s", device_str, rev_str); else - snprintf(buf, buf_size, "%s - Rev: unknown (0x%04" PRIx16 ")", device_str, rev_id); + command_print_sameline(cmd, "%s - Rev: unknown (0x%04" PRIx16 ")", device_str, rev_id); return ERROR_OK; } diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 52e3e0e87..4c503db38 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -916,7 +916,7 @@ static int stm32x_auto_probe(struct flash_bank *bank) } /* This method must return a string displaying information about the bank */ -static int stm32x_get_info(struct flash_bank *bank, char *buf, int buf_size) +static int stm32x_get_info(struct flash_bank *bank, struct command_invocation *cmd) { struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; const struct stm32h7x_part_info *info = stm32x_info->part_info; @@ -924,7 +924,7 @@ static int stm32x_get_info(struct flash_bank *bank, char *buf, int buf_size) if (!stm32x_info->probed) { int retval = stm32x_probe(bank); if (retval != ERROR_OK) { - snprintf(buf, buf_size, "Unable to find bank information."); + command_print_sameline(cmd, "Unable to find bank information."); return retval; } } @@ -938,16 +938,16 @@ static int stm32x_get_info(struct flash_bank *bank, char *buf, int buf_size) rev_str = info->revs[i].str; if (rev_str != NULL) { - snprintf(buf, buf_size, "%s - Rev: %s", + command_print_sameline(cmd, "%s - Rev: %s", stm32x_info->part_info->device_str, rev_str); } else { - snprintf(buf, buf_size, + command_print_sameline(cmd, "%s - Rev: unknown (0x%04" PRIx16 ")", stm32x_info->part_info->device_str, rev_id); } } else { - snprintf(buf, buf_size, "Cannot identify target as a STM32H7x"); - return ERROR_FAIL; + command_print_sameline(cmd, "Cannot identify target as a STM32H7x"); + return ERROR_FAIL; } return ERROR_OK; } diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 7e1fe7cec..cd6229548 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -1332,13 +1332,36 @@ static int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id) return (retval == ERROR_OK) ? ERROR_FAIL : retval; } +static const char *get_stm32l4_rev_str(struct flash_bank *bank) +{ + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + const struct stm32l4_part_info *part_info = stm32l4_info->part_info; + assert(part_info); + + const uint16_t rev_id = stm32l4_info->idcode >> 16; + for (unsigned int i = 0; i < part_info->num_revs; i++) { + if (rev_id == part_info->revs[i].rev) + return part_info->revs[i].str; + } + return "'unknown'"; +} + +static const char *get_stm32l4_bank_type_str(struct flash_bank *bank) +{ + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + assert(stm32l4_info->part_info); + assert(stm32l4_info->probed); + return stm32l4_is_otp(bank) ? "OTP" : + stm32l4_info->dual_bank_mode ? "Flash dual" : + "Flash single"; +} + static int stm32l4_probe(struct flash_bank *bank) { struct target *target = bank->target; struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; const struct stm32l4_part_info *part_info; uint16_t flash_size_kb = 0xffff; - uint32_t device_id; uint32_t options; stm32l4_info->probed = false; @@ -1348,7 +1371,9 @@ static int stm32l4_probe(struct flash_bank *bank) if (retval != ERROR_OK) return retval; - device_id = stm32l4_info->idcode & 0xFFF; + const uint32_t device_id = stm32l4_info->idcode & 0xFFF; + const uint16_t rev_id = stm32l4_info->idcode >> 16; + const char *rev_str = get_stm32l4_rev_str(bank); for (unsigned int n = 0; n < ARRAY_SIZE(stm32l4_parts); n++) { if (device_id == stm32l4_parts[n].id) { @@ -1365,12 +1390,9 @@ static int stm32l4_probe(struct flash_bank *bank) part_info = stm32l4_info->part_info; stm32l4_info->flash_regs = stm32l4_info->part_info->default_flash_regs; - char device_info[1024]; - retval = bank->driver->info(bank, device_info, sizeof(device_info)); - if (retval != ERROR_OK) - return retval; - - LOG_INFO("device idcode = 0x%08" PRIx32 " (%s)", stm32l4_info->idcode, device_info); + LOG_INFO("device idcode = 0x%08" PRIx32 " (%s - Rev %s : 0x%04x - %s-bank)", + stm32l4_info->idcode, part_info->device_str, rev_str, rev_id, + get_stm32l4_bank_type_str(bank)); /* read flash option register */ retval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_OPTR_INDEX, &options); @@ -1610,33 +1632,19 @@ static int stm32l4_auto_probe(struct flash_bank *bank) return stm32l4_probe(bank); } -static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_stm32l4_info(struct flash_bank *bank, struct command_invocation *cmd) { struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; const struct stm32l4_part_info *part_info = stm32l4_info->part_info; if (part_info) { - const char *rev_str = NULL; - uint16_t rev_id = stm32l4_info->idcode >> 16; - for (unsigned int i = 0; i < part_info->num_revs; i++) { - if (rev_id == part_info->revs[i].rev) { - rev_str = part_info->revs[i].str; - break; - } - } - - int buf_len = snprintf(buf, buf_size, "%s - Rev %s : 0x%04x", - part_info->device_str, rev_str ? rev_str : "'unknown'", rev_id); - + const uint16_t rev_id = stm32l4_info->idcode >> 16; + command_print_sameline(cmd, "%s - Rev %s : 0x%04x", part_info->device_str, + get_stm32l4_rev_str(bank), rev_id); if (stm32l4_info->probed) - snprintf(buf + buf_len, buf_size - buf_len, " - %s-bank", - stm32l4_is_otp(bank) ? "OTP" : - stm32l4_info->dual_bank_mode ? "Flash dual" : "Flash single"); - - return ERROR_OK; + command_print_sameline(cmd, " - %s-bank", get_stm32l4_bank_type_str(bank)); } else { - snprintf(buf, buf_size, "Cannot identify target as an %s device", device_families); - return ERROR_FAIL; + command_print_sameline(cmd, "Cannot identify target as an %s device", device_families); } return ERROR_OK; diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c index b014d097d..1ea1b1d0e 100644 --- a/src/flash/nor/stm32lx.c +++ b/src/flash/nor/stm32lx.c @@ -870,7 +870,7 @@ static int stm32lx_auto_probe(struct flash_bank *bank) } /* This method must return a string displaying information about the bank */ -static int stm32lx_get_info(struct flash_bank *bank, char *buf, int buf_size) +static int stm32lx_get_info(struct flash_bank *bank, struct command_invocation *cmd) { struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; const struct stm32lx_part_info *info = &stm32lx_info->part_info; @@ -880,8 +880,7 @@ static int stm32lx_get_info(struct flash_bank *bank, char *buf, int buf_size) if (!stm32lx_info->probed) { int retval = stm32lx_probe(bank); if (retval != ERROR_OK) { - snprintf(buf, buf_size, - "Unable to find bank information."); + command_print_sameline(cmd, "Unable to find bank information."); return retval; } } @@ -891,13 +890,9 @@ static int stm32lx_get_info(struct flash_bank *bank, char *buf, int buf_size) rev_str = info->revs[i].str; if (rev_str != NULL) { - snprintf(buf, buf_size, - "%s - Rev: %s", - info->device_str, rev_str); + command_print_sameline(cmd, "%s - Rev: %s", info->device_str, rev_str); } else { - snprintf(buf, buf_size, - "%s - Rev: unknown (0x%04x)", - info->device_str, rev_id); + command_print_sameline(cmd, "%s - Rev: unknown (0x%04x)", info->device_str, rev_id); } return ERROR_OK; diff --git a/src/flash/nor/stmqspi.c b/src/flash/nor/stmqspi.c index a3555a4a6..978188ec1 100644 --- a/src/flash/nor/stmqspi.c +++ b/src/flash/nor/stmqspi.c @@ -2397,17 +2397,16 @@ static int stmqspi_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int get_stmqspi_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_stmqspi_info(struct flash_bank *bank, struct command_invocation *cmd) { struct stmqspi_flash_bank *stmqspi_info = bank->driver_priv; if (!(stmqspi_info->probed)) { - snprintf(buf, buf_size, - "\nQSPI flash bank not probed yet\n"); + command_print_sameline(cmd, "\nQSPI flash bank not probed yet\n"); return ERROR_FLASH_BANK_NOT_PROBED; } - snprintf(buf, buf_size, "flash%s%s \'%s\', device id = 0x%06" PRIx32 + command_print_sameline(cmd, "flash%s%s \'%s\', device id = 0x%06" PRIx32 ", flash size = %" PRIu32 "%sbytes\n(page size = %" PRIu32 ", read = 0x%02" PRIx8 ", qread = 0x%02" PRIx8 ", pprog = 0x%02" PRIx8 ", mass_erase = 0x%02" PRIx8 diff --git a/src/flash/nor/stmsmi.c b/src/flash/nor/stmsmi.c index f633e3619..662b45953 100644 --- a/src/flash/nor/stmsmi.c +++ b/src/flash/nor/stmsmi.c @@ -631,17 +631,16 @@ static int stmsmi_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int get_stmsmi_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_stmsmi_info(struct flash_bank *bank, struct command_invocation *cmd) { struct stmsmi_flash_bank *stmsmi_info = bank->driver_priv; if (!(stmsmi_info->probed)) { - snprintf(buf, buf_size, - "\nSMI flash bank not probed yet\n"); + command_print_sameline(cmd, "\nSMI flash bank not probed yet\n"); return ERROR_OK; } - snprintf(buf, buf_size, "\nSMI flash information:\n" + command_print_sameline(cmd, "\nSMI flash information:\n" " Device \'%s\' (ID 0x%08" PRIx32 ")\n", stmsmi_info->dev->name, stmsmi_info->dev->device_id); diff --git a/src/flash/nor/str7x.c b/src/flash/nor/str7x.c index e028c1ffd..958b0fa2b 100644 --- a/src/flash/nor/str7x.c +++ b/src/flash/nor/str7x.c @@ -702,13 +702,13 @@ COMMAND_HANDLER(str7x_handle_part_id_command) } #endif -static int get_str7x_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_str7x_info(struct flash_bank *bank, struct command_invocation *cmd) { /* Setting the write protection on a sector is a permanent change but it * can be disabled temporarily. FLASH_NVWPAR reflects the permanent * protection state of the sectors, not the temporary. */ - snprintf(buf, buf_size, "STR7x flash protection info is only valid after a power cycle, " + command_print_sameline(cmd, "STR7x flash protection info is only valid after a power cycle, " "clearing the protection is only temporary and may not be reflected in the current " "info returned."); return ERROR_OK; diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 3f737aca3..199bf2d4e 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -89,7 +89,6 @@ COMMAND_HANDLER(handle_flash_info_command) return retval; if (p != NULL) { - char buf[1024]; int num_blocks; struct flash_sector *block_array; @@ -150,10 +149,10 @@ COMMAND_HANDLER(handle_flash_info_command) } if (p->driver->info != NULL) { - retval = p->driver->info(p, buf, sizeof(buf)); - if (retval == ERROR_OK) - command_print(CMD, "%s", buf); - else + /* Let the flash driver print extra custom info */ + retval = p->driver->info(p, CMD); + command_print_sameline(CMD, "\n"); + if (retval != ERROR_OK) LOG_ERROR("error retrieving flash info"); } } diff --git a/src/flash/nor/tms470.c b/src/flash/nor/tms470.c index 3004682b8..c5d74c30c 100644 --- a/src/flash/nor/tms470.c +++ b/src/flash/nor/tms470.c @@ -1118,26 +1118,20 @@ static int tms470_protect_check(struct flash_bank *bank) /* ---------------------------------------------------------------------- */ -static int get_tms470_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_tms470_info(struct flash_bank *bank, struct command_invocation *cmd) { - int used = 0; struct tms470_flash_bank *tms470_info = bank->driver_priv; if (!tms470_info->device_ident_reg) tms470_read_part_info(bank); if (!tms470_info->device_ident_reg) { - (void)snprintf(buf, buf_size, "Cannot identify target as a TMS470\n"); + command_print_sameline(cmd, "Cannot identify target as a TMS470\n"); return ERROR_FLASH_OPERATION_FAILED; } - used = - snprintf(buf, buf_size, "\ntms470 information: Chip is %s\n", - tms470_info->part_name); - buf += used; - buf_size -= used; - - snprintf(buf, buf_size, "Flash protection level 2 is %s\n", + command_print_sameline(cmd, "\ntms470 information: Chip is %s\n", tms470_info->part_name); + command_print_sameline(cmd, "Flash protection level 2 is %s\n", tms470_check_flash_unlocked(bank->target) == ERROR_OK ? "disabled" : "enabled"); return ERROR_OK; diff --git a/src/flash/nor/virtual.c b/src/flash/nor/virtual.c index 1aa12fecd..c9525d179 100644 --- a/src/flash/nor/virtual.c +++ b/src/flash/nor/virtual.c @@ -172,14 +172,14 @@ static int virtual_auto_probe(struct flash_bank *bank) return ERROR_OK; } -static int virtual_info(struct flash_bank *bank, char *buf, int buf_size) +static int virtual_info(struct flash_bank *bank, struct command_invocation *cmd) { struct flash_bank *master_bank = virtual_get_master_bank(bank); if (master_bank == NULL) return ERROR_FLASH_OPERATION_FAILED; - snprintf(buf, buf_size, "%s driver for flash bank %s at " TARGET_ADDR_FMT, + command_print_sameline(cmd, "%s driver for flash bank %s at " TARGET_ADDR_FMT, bank->driver->name, master_bank->name, master_bank->base); return ERROR_OK; diff --git a/src/flash/nor/w600.c b/src/flash/nor/w600.c index 2506f2b55..cd2aa0182 100644 --- a/src/flash/nor/w600.c +++ b/src/flash/nor/w600.c @@ -362,7 +362,7 @@ static int w600_auto_probe(struct flash_bank *bank) return w600_probe(bank); } -static int get_w600_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_w600_info(struct flash_bank *bank, struct command_invocation *cmd) { uint32_t flash_id; @@ -371,7 +371,7 @@ static int get_w600_info(struct flash_bank *bank, char *buf, int buf_size) if (retval != ERROR_OK) return retval; - snprintf(buf, buf_size, "w600 : 0x%08" PRIx32 "", flash_id); + command_print_sameline(cmd, "w600 : 0x%08" PRIx32 "", flash_id); return ERROR_OK; } diff --git a/src/flash/nor/xcf.c b/src/flash/nor/xcf.c index 01329f47a..33f79f510 100644 --- a/src/flash/nor/xcf.c +++ b/src/flash/nor/xcf.c @@ -581,15 +581,15 @@ FLASH_BANK_COMMAND_HANDLER(xcf_flash_bank_command) return ERROR_OK; } -static int xcf_info(struct flash_bank *bank, char *buf, int buf_size) +static int xcf_info(struct flash_bank *bank, struct command_invocation *cmd) { const struct xcf_priv *priv = bank->driver_priv; if (!priv->probed) { - snprintf(buf, buf_size, "\nXCF flash bank not probed yet\n"); + command_print_sameline(cmd, "\nXCF flash bank not probed yet\n"); return ERROR_OK; } - snprintf(buf, buf_size, "%s", product_name(bank)); + command_print_sameline(cmd, "%s", product_name(bank)); return ERROR_OK; } diff --git a/src/flash/nor/xmc1xxx.c b/src/flash/nor/xmc1xxx.c index 757dd952f..11542ac5b 100644 --- a/src/flash/nor/xmc1xxx.c +++ b/src/flash/nor/xmc1xxx.c @@ -403,7 +403,7 @@ static int xmc1xxx_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int xmc1xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_size) +static int xmc1xxx_get_info_command(struct flash_bank *bank, struct command_invocation *cmd) { uint32_t chipid[8]; int i, retval; @@ -429,7 +429,8 @@ static int xmc1xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_ } LOG_DEBUG("ID[7] = %08" PRIX32, chipid[7]); - snprintf(buf, buf_size, "XMC%" PRIx32 "00 %" PRIX32 " flash %" PRIu32 "KB ROM %" PRIu32 "KB SRAM %" PRIu32 "KB", + command_print_sameline(cmd, + "XMC%" PRIx32 "00 %" PRIX32 " flash %" PRIu32 "KB ROM %" PRIu32 "KB SRAM %" PRIu32 "KB", (chipid[0] >> 12) & 0xff, 0xAA + (chipid[7] >> 28) - 1, (((chipid[6] >> 12) & 0x3f) - 1) * 4, diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c index a032e4d46..a2cf6a0b1 100644 --- a/src/flash/nor/xmc4xxx.c +++ b/src/flash/nor/xmc4xxx.c @@ -805,7 +805,7 @@ abort_write_and_exit: } -static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_size) +static int xmc4xxx_get_info_command(struct flash_bank *bank, struct command_invocation *cmd) { struct xmc4xxx_flash_bank *fb = bank->driver_priv; uint32_t scu_idcode; @@ -914,9 +914,7 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_ break; default: - snprintf(buf, buf_size, - "Cannot identify target as an XMC4xxx. SCU_ID: %"PRIx32"\n", - scu_idcode); + command_print_sameline(cmd, "Cannot identify target as an XMC4xxx. SCU_ID: %"PRIx32 "\n", scu_idcode); return ERROR_OK; } @@ -944,11 +942,9 @@ static int xmc4xxx_get_info_command(struct flash_bank *bank, char *buf, int buf_ } if (rev_str != NULL) - snprintf(buf, buf_size, "%s - Rev: %s%s", - dev_str, rev_str, prot_str); + command_print_sameline(cmd, "%s - Rev: %s%s", dev_str, rev_str, prot_str); else - snprintf(buf, buf_size, "%s - Rev: unknown (0x%01x)%s", - dev_str, rev_id, prot_str); + command_print_sameline(cmd, "%s - Rev: unknown (0x%01x)%s", dev_str, rev_id, prot_str); return ERROR_OK; } From 21e1ebdc8e548f0db5fe5e2f90fb1cfc49cc53b0 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sun, 14 Feb 2021 12:39:33 +0100 Subject: [PATCH 04/27] armv8_dpm: do not read/write non-existent registers Change-Id: I0f3fffa8cf1746569f6acce0233e9544d3862f51 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/6062 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/armv8_dpm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index 6ef8c33de..b36ef835c 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -782,7 +782,7 @@ int armv8_dpm_read_current_registers(struct arm_dpm *dpm) struct arm_reg *arm_reg; r = armv8_reg_current(arm, i); - if (r->valid) + if (!r->exist || r->valid) continue; /* Skip reading FP-SIMD registers */ @@ -922,6 +922,9 @@ int armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) for (unsigned i = 1; i < cache->num_regs; i++) { struct arm_reg *r; + /* skip non-existent */ + if (!cache->reg_list[i].exist) + continue; /* skip PC and CPSR */ if (i == ARMV8_PC || i == ARMV8_xPSR) continue; @@ -1047,7 +1050,7 @@ static int armv8_dpm_full_context(struct target *target) for (unsigned i = 0; i < cache->num_regs; i++) { struct arm_reg *r; - if (cache->reg_list[i].valid) + if (!cache->reg_list[i].exist || cache->reg_list[i].valid) continue; r = cache->reg_list[i].arch_info; From 708284a1accfa01c7a14ea7d7cd588000776d6b7 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sun, 14 Feb 2021 13:21:36 +0100 Subject: [PATCH 05/27] arm_dpm: do not read/write non-existent registers Change-Id: I6a991899bb178ee0c6b41870a45d0a9439d9dc1e Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/6063 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/target/arm_dpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index 058f0df09..d1f574856 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -514,7 +514,7 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) continue; if (arm->cpsr == cache->reg_list + i) continue; - if (!cache->reg_list[i].dirty) + if (!cache->reg_list[i].exist || !cache->reg_list[i].dirty) continue; r = cache->reg_list[i].arch_info; @@ -763,7 +763,7 @@ static int arm_dpm_full_context(struct target *target) for (unsigned i = 0; i < cache->num_regs; i++) { struct arm_reg *r; - if (cache->reg_list[i].valid) + if (!cache->reg_list[i].exist || cache->reg_list[i].valid) continue; r = cache->reg_list[i].arch_info; From cb5d9e0098a62b388fcfc7c89ddb6cda2be77a38 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sun, 14 Feb 2021 13:22:03 +0100 Subject: [PATCH 06/27] armv4_5: do not read/write non-existent registers Change-Id: I4a0c401a325e57ba5d4d93d83b7e6b71a4d0865e Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/6064 Tested-by: jenkins Reviewed-by: Marc Schink Reviewed-by: Antonio Borneo --- src/target/armv4_5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 8ba913646..084a6f9b2 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1681,7 +1681,7 @@ static int arm_full_context(struct target *target) int retval = ERROR_OK; for (; num_regs && retval == ERROR_OK; num_regs--, reg++) { - if (reg->valid) + if (!reg->exist || reg->valid) continue; retval = armv4_5_get_core_reg(reg); } From 3e8ca67d1f9309d6f7860bdb6e9ad80d60f3ae6e Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sun, 13 Jun 2021 10:49:17 +0200 Subject: [PATCH 07/27] target: Rename 'linked_BRP' to 'linked_brp' Change-Id: I9dd67ac3e8cd5dd9cdeffce56020b387a8f298fa Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/6316 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/aarch64.c | 6 +++--- src/target/breakpoints.h | 2 +- src/target/cortex_a.c | 6 +++--- src/target/nds32.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/target/aarch64.c b/src/target/aarch64.c index ef00fd131..171c28615 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -1433,7 +1433,7 @@ static int aarch64_set_hybrid_breakpoint(struct target *target, struct breakpoin } breakpoint->set = brp_1 + 1; - breakpoint->linked_BRP = brp_2; + breakpoint->linked_brp = brp_2; control_CTX = ((CTX_machmode & 0x7) << 20) | (brp_2 << 16) | (0 << 14) @@ -1495,7 +1495,7 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br if (breakpoint->type == BKPT_HARD) { if ((breakpoint->address != 0) && (breakpoint->asid != 0)) { int brp_i = breakpoint->set - 1; - int brp_j = breakpoint->linked_BRP; + int brp_j = breakpoint->linked_brp; if ((brp_i < 0) || (brp_i >= aarch64->brp_num)) { LOG_DEBUG("Invalid BRP number in breakpoint"); return ERROR_OK; @@ -1545,7 +1545,7 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br if (retval != ERROR_OK) return retval; - breakpoint->linked_BRP = 0; + breakpoint->linked_brp = 0; breakpoint->set = 0; return ERROR_OK; diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h index 8c247f7a9..b4a3511d2 100644 --- a/src/target/breakpoints.h +++ b/src/target/breakpoints.h @@ -43,7 +43,7 @@ struct breakpoint { uint8_t *orig_instr; struct breakpoint *next; uint32_t unique_id; - int linked_BRP; + int linked_brp; }; struct watchpoint { diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index ec02d179f..7af0d3d7e 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1444,7 +1444,7 @@ static int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoi } breakpoint->set = brp_1 + 1; - breakpoint->linked_BRP = brp_2; + breakpoint->linked_brp = brp_2; control_CTX = ((CTX_machmode & 0x7) << 20) | (brp_2 << 16) | (0 << 14) @@ -1500,7 +1500,7 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b if (breakpoint->type == BKPT_HARD) { if ((breakpoint->address != 0) && (breakpoint->asid != 0)) { int brp_i = breakpoint->set - 1; - int brp_j = breakpoint->linked_BRP; + int brp_j = breakpoint->linked_brp; if ((brp_i < 0) || (brp_i >= cortex_a->brp_num)) { LOG_DEBUG("Invalid BRP number in breakpoint"); return ERROR_OK; @@ -1539,7 +1539,7 @@ static int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *b brp_list[brp_j].value); if (retval != ERROR_OK) return retval; - breakpoint->linked_BRP = 0; + breakpoint->linked_brp = 0; breakpoint->set = 0; return ERROR_OK; diff --git a/src/target/nds32.c b/src/target/nds32.c index add66b22f..cc6e2da44 100644 --- a/src/target/nds32.c +++ b/src/target/nds32.c @@ -1660,7 +1660,7 @@ int nds32_init_arch_info(struct target *target, struct nds32 *nds32) nds32->syscall_break.orig_instr = NULL; nds32->syscall_break.next = NULL; nds32->syscall_break.unique_id = 0x515CAll + target->target_number; - nds32->syscall_break.linked_BRP = 0; + nds32->syscall_break.linked_brp = 0; nds32_reg_init(); From b19505a34377c2bade1aa129108b0c6aec577512 Mon Sep 17 00:00:00 2001 From: Diego Herranz Date: Fri, 11 Jun 2021 08:58:04 +0100 Subject: [PATCH 08/27] contrib/itmdump.c: fix implicit declaration warning atoi used but stdlib.h wasn't included. Also, include statements reordered alphabetically. Change-Id: I7fcdbf3fa940a172204ec811399e1a7fdebdc979 Signed-off-by: Diego Herranz Reviewed-on: http://openocd.zylin.com/6312 Tested-by: jenkins Reviewed-by: Antonio Borneo --- contrib/itmdump.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/itmdump.c b/contrib/itmdump.c index 24aa34f32..88099040a 100644 --- a/contrib/itmdump.c +++ b/contrib/itmdump.c @@ -39,8 +39,9 @@ #include #include -#include #include +#include +#include #include #include From f69adafb3dd252eaf6b269b7993b29d3c78a91c8 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 11 May 2021 09:28:00 +0100 Subject: [PATCH 09/27] target/arm: optimize architecture flags In target/arm.h the struct arm do contain 3 flags to retain architecture version for some tweaks. The proposal is to have only one enumerated flag 'arch' for the same purpose. Change-Id: Ia5d5accfed8158ca21eb54af2fdea8e36f0266ae Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/6229 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nand/arm_io.c | 4 ++-- src/flash/nor/stm32lx.c | 2 +- src/rtos/riot.c | 2 +- src/target/arm.h | 19 +++++++++++-------- src/target/arm720t.c | 2 +- src/target/arm7tdmi.c | 2 +- src/target/arm9tdmi.c | 2 +- src/target/armv4_5.c | 6 +++--- src/target/cortex_m.c | 16 ++++++++-------- 9 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/flash/nand/arm_io.c b/src/flash/nand/arm_io.c index e319f9585..705470e77 100644 --- a/src/flash/nand/arm_io.c +++ b/src/flash/nand/arm_io.c @@ -173,7 +173,7 @@ int arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size) buf_set_u32(reg_params[2].value, 0, 32, size); /* armv4 must exit using a hardware breakpoint */ - if (arm->is_armv4) + if (arm->arch == ARM_ARCH_V4) exit_var = nand->copy_area->address + target_code_size - 4; /* use alg to write data from work area to NAND chip */ @@ -279,7 +279,7 @@ int arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size) buf_set_u32(reg_params[2].value, 0, 32, size); /* armv4 must exit using a hardware breakpoint */ - if (arm->is_armv4) + if (arm->arch == ARM_ARCH_V4) exit_var = nand->copy_area->address + target_code_size - 4; /* use alg to write data from NAND chip to work area */ diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c index 1ea1b1d0e..5ca424b87 100644 --- a/src/flash/nor/stm32lx.c +++ b/src/flash/nor/stm32lx.c @@ -718,7 +718,7 @@ static int stm32lx_read_id_code(struct target *target, uint32_t *id) { struct armv7m_common *armv7m = target_to_armv7m(target); int retval; - if (armv7m->arm.is_armv6m == true) + if (armv7m->arm.arch == ARM_ARCH_V6M) retval = target_read_u32(target, DBGMCU_IDCODE_L0, id); else /* read stm32 device id register */ diff --git a/src/rtos/riot.c b/src/rtos/riot.c index dcba8381c..9165fe11b 100644 --- a/src/rtos/riot.c +++ b/src/rtos/riot.c @@ -416,7 +416,7 @@ static int riot_create(struct target *target) /* Stacking is different depending on architecture */ struct armv7m_common *armv7m_target = target_to_armv7m(target); - if (armv7m_target->arm.is_armv6m) + if (armv7m_target->arm.arch == ARM_ARCH_V6M) stacking_info = &rtos_riot_cortex_m0_stacking; else if (is_armv7m(armv7m_target)) stacking_info = &rtos_riot_cortex_m34_stacking; diff --git a/src/target/arm.h b/src/target/arm.h index d97a95edf..f403b8f8a 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -60,6 +60,15 @@ enum arm_core_type { ARM_CORE_TYPE_M_PROFILE, }; +/** ARM Architecture specifying the version and the profile */ +enum arm_arch { + ARM_ARCH_UNKNOWN, + ARM_ARCH_V4, + ARM_ARCH_V6M, + ARM_ARCH_V7M, + ARM_ARCH_V8M, +}; + /** * Represent state of an ARM core. * @@ -191,14 +200,8 @@ struct arm { /** Record the current core state: ARM, Thumb, or otherwise. */ enum arm_state core_state; - /** Flag reporting unavailability of the BKPT instruction. */ - bool is_armv4; - - /** Flag reporting armv6m based core. */ - bool is_armv6m; - - /** Flag reporting armv8m based core. */ - bool is_armv8m; + /** ARM architecture version */ + enum arm_arch arch; /** Floating point or VFP version, 0 if disabled. */ int arm_vfp_version; diff --git a/src/target/arm720t.c b/src/target/arm720t.c index daa44e46a..bff20a334 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -427,7 +427,7 @@ static int arm720t_target_create(struct target *target, Jim_Interp *interp) { struct arm720t_common *arm720t = calloc(1, sizeof(*arm720t)); - arm720t->arm7_9_common.arm.is_armv4 = true; + arm720t->arm7_9_common.arm.arch = ARM_ARCH_V4; return arm720t_init_arch_info(target, arm720t, target->tap); } diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index 10263f40a..b0348392f 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -686,7 +686,7 @@ static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp) arm7_9 = calloc(1, sizeof(struct arm7_9_common)); arm7tdmi_init_arch_info(target, arm7_9, target->tap); - arm7_9->arm.is_armv4 = true; + arm7_9->arm.arch = ARM_ARCH_V4; return ERROR_OK; } diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 4810c2b16..2a32f1127 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -781,7 +781,7 @@ static int arm9tdmi_target_create(struct target *target, Jim_Interp *interp) struct arm7_9_common *arm7_9 = calloc(1, sizeof(struct arm7_9_common)); arm9tdmi_init_arch_info(target, arm7_9, target->tap); - arm7_9->arm.is_armv4 = true; + arm7_9->arm.arch = ARM_ARCH_V4; return ERROR_OK; } diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 084a6f9b2..6378ea66e 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1347,7 +1347,7 @@ int armv4_5_run_algorithm_inner(struct target *target, } /* armv5 and later can terminate with BKPT instruction; less overhead */ - if (!exit_point && arm->is_armv4) { + if (!exit_point && arm->arch == ARM_ARCH_V4) { LOG_ERROR("ARMv4 target needs HW breakpoint location"); return ERROR_FAIL; } @@ -1568,7 +1568,7 @@ int arm_checksum_memory(struct target *target, int timeout = 20000 * (1 + (count / (1024 * 1024))); /* armv4 must exit using a hardware breakpoint */ - if (arm->is_armv4) + if (arm->arch == ARM_ARCH_V4) exit_var = crc_algorithm->address + sizeof(arm_crc_code_le) - 8; retval = target_run_algorithm(target, 0, NULL, 2, reg_params, @@ -1649,7 +1649,7 @@ int arm_blank_check_memory(struct target *target, buf_set_u32(reg_params[2].value, 0, 32, erased_value); /* armv4 must exit using a hardware breakpoint */ - if (arm->is_armv4) + if (arm->arch == ARM_ARCH_V4) exit_var = check_algorithm->address + sizeof(check_code_le) - 4; retval = target_run_algorithm(target, 0, NULL, 3, reg_params, diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 941fef16a..e442fc3b6 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -504,7 +504,7 @@ static int cortex_m_debug_entry(struct target *target) /* examine PE security state */ bool secure_state = false; - if (armv7m->arm.is_armv8m) { + if (armv7m->arm.arch == ARM_ARCH_V8M) { uint32_t dscsr; retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DSCSR, &dscsr); @@ -1645,7 +1645,7 @@ static int cortex_m_read_memory(struct target *target, target_addr_t address, { struct armv7m_common *armv7m = target_to_armv7m(target); - if (armv7m->arm.is_armv6m) { + if (armv7m->arm.arch == ARM_ARCH_V6M) { /* armv6m does not handle unaligned memory access */ if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) return ERROR_TARGET_UNALIGNED_ACCESS; @@ -1659,7 +1659,7 @@ static int cortex_m_write_memory(struct target *target, target_addr_t address, { struct armv7m_common *armv7m = target_to_armv7m(target); - if (armv7m->arm.is_armv6m) { + if (armv7m->arm.arch == ARM_ARCH_V6M) { /* armv6m does not handle unaligned memory access */ if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) return ERROR_TARGET_UNALIGNED_ACCESS; @@ -2005,7 +2005,7 @@ int cortex_m_examine(struct target *target) unsigned int core = (cpuid >> 4) & 0xf; /* Check if it is an ARMv8-M core */ - armv7m->arm.is_armv8m = true; + armv7m->arm.arch = ARM_ARCH_V8M; switch (cpuid & ARM_CPUID_PARTNO_MASK) { case CORTEX_M23_PARTNO: @@ -2021,7 +2021,7 @@ int cortex_m_examine(struct target *target) core = 55; break; default: - armv7m->arm.is_armv8m = false; + armv7m->arm.arch = ARM_ARCH_V7M; break; } @@ -2063,18 +2063,18 @@ int cortex_m_examine(struct target *target) } } else if (core == 0) { /* Cortex-M0 does not support unaligned memory access */ - armv7m->arm.is_armv6m = true; + armv7m->arm.arch = ARM_ARCH_V6M; } /* VECTRESET is supported only on ARMv7-M cores */ - cortex_m->vectreset_supported = !armv7m->arm.is_armv8m && !armv7m->arm.is_armv6m; + cortex_m->vectreset_supported = armv7m->arm.arch == ARM_ARCH_V7M; /* 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) + if (armv7m->arm.arch != ARM_ARCH_V8M) for (size_t idx = ARMV8M_FIRST_REG; idx <= ARMV8M_LAST_REG; idx++) armv7m->arm.core_cache->reg_list[idx].exist = false; From 11857607293e1b27b43c307c3f6fba6ebbce90a8 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 11 May 2021 14:03:47 +0100 Subject: [PATCH 10/27] cortex_m: enhance core and arch detection Rework core detection by adding cortex_m_partno enum to detect all CPUs using the same method. Instead of checking the core PARTNO then assign the arch, use the stored information within cortex_m parts[] with the flags inside which can help simplifying a bit the cortex_m_examine code. This change fixes: - the Cortex-M1 detection as ARMv6-M Core (was managed as ARMv7-M) - the displayed CPU name for Cortex-M0+ (was displayed Cortex-M0) Change-Id: I40b6e03f7cf3664c85e297adfc25323196dfe90b Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/6233 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/cortex_m.c | 116 +++++++++++++++++++++++++++++------------- src/target/cortex_m.h | 33 +++++++++--- 2 files changed, 108 insertions(+), 41 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index e442fc3b6..d0256b134 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -52,6 +52,66 @@ * any longer. */ +/* Supported Cortex-M Cores */ +static const struct cortex_m_part_info cortex_m_parts[] = { + { + .partno = CORTEX_M0_PARTNO, + .name = "Cortex-M0", + .arch = ARM_ARCH_V6M, + }, + { + .partno = CORTEX_M0P_PARTNO, + .name = "Cortex-M0+", + .arch = ARM_ARCH_V6M, + }, + { + .partno = CORTEX_M1_PARTNO, + .name = "Cortex-M1", + .arch = ARM_ARCH_V6M, + }, + { + .partno = CORTEX_M3_PARTNO, + .name = "Cortex-M3", + .arch = ARM_ARCH_V7M, + .flags = CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K, + }, + { + .partno = CORTEX_M4_PARTNO, + .name = "Cortex-M4", + .arch = ARM_ARCH_V7M, + .flags = CORTEX_M_F_HAS_FPV4 | CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K, + }, + { + .partno = CORTEX_M7_PARTNO, + .name = "Cortex-M7", + .arch = ARM_ARCH_V7M, + .flags = CORTEX_M_F_HAS_FPV5, + }, + { + .partno = CORTEX_M23_PARTNO, + .name = "Cortex-M23", + .arch = ARM_ARCH_V8M, + }, + { + .partno = CORTEX_M33_PARTNO, + .name = "Cortex-M33", + .arch = ARM_ARCH_V8M, + .flags = CORTEX_M_F_HAS_FPV5, + }, + { + .partno = CORTEX_M35P_PARTNO, + .name = "Cortex-M35P", + .arch = ARM_ARCH_V8M, + .flags = CORTEX_M_F_HAS_FPV5, + }, + { + .partno = CORTEX_M55_PARTNO, + .name = "Cortex-M55", + .arch = ARM_ARCH_V8M, + .flags = CORTEX_M_F_HAS_FPV5, + }, +}; + /* forward declarations */ static int cortex_m_store_core_reg_u32(struct target *target, uint32_t num, uint32_t value); @@ -2001,35 +2061,27 @@ int cortex_m_examine(struct target *target) if (retval != ERROR_OK) return retval; - /* Get CPU Type */ - unsigned int core = (cpuid >> 4) & 0xf; + /* Get ARCH and CPU types */ + const enum cortex_m_partno core_partno = (cpuid & ARM_CPUID_PARTNO_MASK) >> ARM_CPUID_PARTNO_POS; - /* Check if it is an ARMv8-M core */ - armv7m->arm.arch = ARM_ARCH_V8M; - - switch (cpuid & ARM_CPUID_PARTNO_MASK) { - case CORTEX_M23_PARTNO: - core = 23; - break; - case CORTEX_M33_PARTNO: - core = 33; - break; - case CORTEX_M35P_PARTNO: - core = 35; - break; - case CORTEX_M55_PARTNO: - core = 55; - break; - default: - armv7m->arm.arch = ARM_ARCH_V7M; + for (unsigned int n = 0; n < ARRAY_SIZE(cortex_m_parts); n++) { + if (core_partno == cortex_m_parts[n].partno) { + cortex_m->core_info = &cortex_m_parts[n]; break; + } } + if (!cortex_m->core_info) { + LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno); + return ERROR_FAIL; + } - LOG_DEBUG("Cortex-M%d r%" PRId8 "p%" PRId8 " processor detected", - core, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf)); + armv7m->arm.arch = cortex_m->core_info->arch; + + LOG_DEBUG("%s r%" PRId8 "p%" PRId8 " processor detected", + cortex_m->core_info->name, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf)); cortex_m->maskints_erratum = false; - if (core == 7) { + if (core_partno == CORTEX_M7_PARTNO) { uint8_t rev, patch; rev = (cpuid >> 20) & 0xf; patch = (cpuid >> 0) & 0xf; @@ -2040,30 +2092,27 @@ int cortex_m_examine(struct target *target) } LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); - if (core == 4) { + if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV4) { 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", core); + LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m->core_info->name); armv7m->fp_feature = FPV4_SP; } - } else if (core == 7 || core == 33 || core == 35 || core == 55) { + } else if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV5) { 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", core); + LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m->core_info->name); 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", core); + LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m->core_info->name); armv7m->fp_feature = FPV5_DP; } - } else if (core == 0) { - /* Cortex-M0 does not support unaligned memory access */ - armv7m->arm.arch = ARM_ARCH_V6M; } /* VECTRESET is supported only on ARMv7-M cores */ @@ -2079,13 +2128,10 @@ int cortex_m_examine(struct target *target) armv7m->arm.core_cache->reg_list[idx].exist = false; if (!armv7m->stlink) { - if (core == 3 || core == 4) + if (cortex_m->core_info->flags & CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K) /* 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 (core == 7) - /* Cortex-M7 has only 1024 bytes autoincrement range */ - armv7m->debug_ap->tar_autoincr_block = (1 << 10); } /* Enable debug requests */ diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 0f221ffff..3ba8a016d 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -42,12 +42,33 @@ #define CPUID 0xE000ED00 -#define ARM_CPUID_PARTNO_MASK 0xFFF0 +#define ARM_CPUID_PARTNO_POS 4 +#define ARM_CPUID_PARTNO_MASK (0xFFF << ARM_CPUID_PARTNO_POS) -#define CORTEX_M23_PARTNO 0xD200 -#define CORTEX_M33_PARTNO 0xD210 -#define CORTEX_M35P_PARTNO 0xD310 -#define CORTEX_M55_PARTNO 0xD220 +enum cortex_m_partno { + CORTEX_M0_PARTNO = 0xC20, + CORTEX_M1_PARTNO = 0xC21, + CORTEX_M3_PARTNO = 0xC23, + CORTEX_M4_PARTNO = 0xC24, + CORTEX_M7_PARTNO = 0xC27, + CORTEX_M0P_PARTNO = 0xC60, + CORTEX_M23_PARTNO = 0xD20, + CORTEX_M33_PARTNO = 0xD21, + CORTEX_M35P_PARTNO = 0xD31, + CORTEX_M55_PARTNO = 0xD22, +}; + +/* Relevant Cortex-M flags, used in struct cortex_m_part_info.flags */ +#define CORTEX_M_F_HAS_FPV4 BIT(0) +#define CORTEX_M_F_HAS_FPV5 BIT(1) +#define CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K BIT(2) + +struct cortex_m_part_info { + enum cortex_m_partno partno; + const char *name; + enum arm_arch arch; + uint32_t flags; +}; /* Debug Control Block */ #define DCB_DHCSR 0xE000EDF0 @@ -211,9 +232,9 @@ struct cortex_m_common { enum cortex_m_soft_reset_config soft_reset_config; bool vectreset_supported; - enum cortex_m_isrmasking_mode isrmasking_mode; + const struct cortex_m_part_info *core_info; struct armv7m_common armv7m; int apsel; From f5898bd93ff8b4d36a9aa781541de6f75d24debf Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Thu, 13 May 2021 14:28:24 +0100 Subject: [PATCH 11/27] flash/stm32fxx.c: do not read CPUID as this info is stored in cortex_m_common In these drivers we read CPUID to check the Cortex-M PARTNO, but now the PARTNO is stored in struct cortex_m_common.core_info. Change-Id: I5bb3b95210ab6e23b8e1252686dd81015740bf68 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/6240 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/stm32f1x.c | 61 ++++++++++++++++++++-------------------- src/flash/nor/stm32f2x.c | 20 ++++--------- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 91f2aef86..fbcf83afb 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -29,7 +29,7 @@ #include "imp.h" #include #include -#include +#include /* stm32x register locations */ @@ -623,34 +623,32 @@ cleanup: static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id) { - /* This check the device CPUID core register to detect - * the M0 from the M3 devices. */ - struct target *target = bank->target; - uint32_t cpuid, device_id_register = 0; + struct cortex_m_common *cortex_m = target_to_cm(target); + uint32_t device_id_register = 0; - /* Get the CPUID from the ARM Core - * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0432c/DDI0432C_cortex_m0_r0p0_trm.pdf 4.2.1 */ - int retval = target_read_u32(target, 0xE000ED00, &cpuid); - if (retval != ERROR_OK) - return retval; + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } - if (((cpuid >> 4) & 0xFFF) == 0xC20) { - /* 0xC20 is M0 devices */ + switch (cortex_m->core_info->partno) { + case CORTEX_M0_PARTNO: /* STM32F0x devices */ device_id_register = 0x40015800; - } else if (((cpuid >> 4) & 0xFFF) == 0xC23) { - /* 0xC23 is M3 devices */ + break; + case CORTEX_M3_PARTNO: /* STM32F1x devices */ device_id_register = 0xE0042000; - } else if (((cpuid >> 4) & 0xFFF) == 0xC24) { - /* 0xC24 is M4 devices */ + break; + case CORTEX_M4_PARTNO: /* STM32F3x devices */ device_id_register = 0xE0042000; - } else { + break; + default: LOG_ERROR("Cannot identify target as a stm32x"); return ERROR_FAIL; } /* read stm32 device id register */ - retval = target_read_u32(target, device_id_register, device_id); + int retval = target_read_u32(target, device_id_register, device_id); if (retval != ERROR_OK) return retval; @@ -660,27 +658,30 @@ static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id) static int stm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_size_in_kb) { struct target *target = bank->target; - uint32_t cpuid, flash_size_reg; + struct cortex_m_common *cortex_m = target_to_cm(target); + uint32_t flash_size_reg; - int retval = target_read_u32(target, 0xE000ED00, &cpuid); - if (retval != ERROR_OK) - return retval; + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } - if (((cpuid >> 4) & 0xFFF) == 0xC20) { - /* 0xC20 is M0 devices */ + switch (cortex_m->core_info->partno) { + case CORTEX_M0_PARTNO: /* STM32F0x devices */ flash_size_reg = 0x1FFFF7CC; - } else if (((cpuid >> 4) & 0xFFF) == 0xC23) { - /* 0xC23 is M3 devices */ + break; + case CORTEX_M3_PARTNO: /* STM32F1x devices */ flash_size_reg = 0x1FFFF7E0; - } else if (((cpuid >> 4) & 0xFFF) == 0xC24) { - /* 0xC24 is M4 devices */ + break; + case CORTEX_M4_PARTNO: /* STM32F3x devices */ flash_size_reg = 0x1FFFF7CC; - } else { + break; + default: LOG_ERROR("Cannot identify target as a stm32x"); return ERROR_FAIL; } - retval = target_read_u16(target, flash_size_reg, flash_size_in_kb); + int retval = target_read_u16(target, flash_size_reg, flash_size_in_kb); if (retval != ERROR_OK) return retval; diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c index 44f06f4fd..f718e3b98 100644 --- a/src/flash/nor/stm32f2x.c +++ b/src/flash/nor/stm32f2x.c @@ -29,7 +29,7 @@ #include "imp.h" #include #include -#include +#include /* Regarding performance: * @@ -968,25 +968,17 @@ static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id) * Only effects Rev A silicon */ struct target *target = bank->target; - uint32_t cpuid; + struct cortex_m_common *cortex_m = target_to_cm(target); /* read stm32 device id register */ int retval = target_read_u32(target, 0xE0042000, device_id); if (retval != ERROR_OK) return retval; - if ((*device_id & 0xfff) == 0x411) { - /* read CPUID reg to check core type */ - retval = target_read_u32(target, 0xE000ED00, &cpuid); - if (retval != ERROR_OK) - return retval; - - /* check for cortex_m4 */ - if (((cpuid >> 4) & 0xFFF) == 0xC24) { - *device_id &= ~((0xFFFF << 16) | 0xfff); - *device_id |= (0x1000 << 16) | 0x413; - LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE"); - } + if ((*device_id & 0xfff) == 0x411 && cortex_m->core_info->partno == CORTEX_M4_PARTNO) { + *device_id &= ~((0xFFFF << 16) | 0xfff); + *device_id |= (0x1000 << 16) | 0x413; + LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE"); } return retval; } From 4bb1d8b45ecd768b972efb1e3e9cf6e55336f8fd Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 4 Jun 2021 14:31:57 +0200 Subject: [PATCH 12/27] target/register: Minor code cleanup Change-Id: Ie02a112c0339ae5d3b3763483e493370b487be98 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/6294 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/register.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/target/register.c b/src/target/register.c index 4ddda6e6b..638747560 100644 --- a/src/target/register.c +++ b/src/target/register.c @@ -39,21 +39,20 @@ struct reg *register_get_by_number(struct reg_cache *first, uint32_t reg_num, bool search_all) { - unsigned i; struct reg_cache *cache = first; while (cache) { - for (i = 0; i < cache->num_regs; i++) { - if (cache->reg_list[i].exist == false) + for (unsigned int i = 0; i < cache->num_regs; i++) { + if (!cache->reg_list[i].exist) continue; if (cache->reg_list[i].number == reg_num) return &(cache->reg_list[i]); } - if (search_all) - cache = cache->next; - else + if (!search_all) break; + + cache = cache->next; } return NULL; @@ -62,21 +61,20 @@ struct reg *register_get_by_number(struct reg_cache *first, struct reg *register_get_by_name(struct reg_cache *first, const char *name, bool search_all) { - unsigned i; struct reg_cache *cache = first; while (cache) { - for (i = 0; i < cache->num_regs; i++) { - if (cache->reg_list[i].exist == false) + for (unsigned int i = 0; i < cache->num_regs; i++) { + if (!cache->reg_list[i].exist) continue; if (strcmp(cache->reg_list[i].name, name) == 0) return &(cache->reg_list[i]); } - if (search_all) - cache = cache->next; - else + if (!search_all) break; + + cache = cache->next; } return NULL; @@ -108,8 +106,8 @@ void register_cache_invalidate(struct reg_cache *cache) { struct reg *reg = cache->reg_list; - for (unsigned n = cache->num_regs; n != 0; n--, reg++) { - if (reg->exist == false) + for (unsigned int n = cache->num_regs; n != 0; n--, reg++) { + if (!reg->exist) continue; reg->valid = false; reg->dirty = false; From da770c4fbb9ea20904caf3fcf4b51d7d064d11a8 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 4 Jun 2021 14:38:17 +0200 Subject: [PATCH 13/27] Use boolean argument for register_get_by_name() Change-Id: Ie913630c6ab3b600532d8e375e2fc11ca202cf5e Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/6295 Tested-by: jenkins Reviewed-by: Jan Matyas Reviewed-by: Antonio Borneo --- src/target/armv4_5.c | 4 ++-- src/target/armv7m.c | 4 ++-- src/target/dsp563xx.c | 4 ++-- src/target/mips32.c | 4 ++-- src/target/nds32.c | 2 +- src/target/riscv/riscv.c | 10 +++++----- src/target/stm8.c | 4 ++-- src/target/target.c | 4 ++-- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 6378ea66e..4e1febe04 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1380,7 +1380,7 @@ int armv4_5_run_algorithm_inner(struct target *target, if (reg_params[i].direction == PARAM_IN) continue; - struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, 0); + struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); return ERROR_COMMAND_SYNTAX_ERROR; @@ -1452,7 +1452,7 @@ int armv4_5_run_algorithm_inner(struct target *target, struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, - 0); + false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); retval = ERROR_COMMAND_SYNTAX_ERROR; diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 11770b5b5..a9a5a381d 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -559,7 +559,7 @@ int armv7m_start_algorithm(struct target *target, continue; struct reg *reg = - register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, 0); + register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, false); /* uint32_t regvalue; */ if (!reg) { @@ -675,7 +675,7 @@ int armv7m_wait_algorithm(struct target *target, if (reg_params[i].direction != PARAM_OUT) { struct reg *reg = register_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, - 0); + false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c index 21bed8996..81ea21e81 100644 --- a/src/target/dsp563xx.c +++ b/src/target/dsp563xx.c @@ -1402,7 +1402,7 @@ static int dsp563xx_run_algorithm(struct target *target, struct reg *reg = register_get_by_name(dsp563xx->core_cache, reg_params[i].reg_name, - 0); + false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); @@ -1444,7 +1444,7 @@ static int dsp563xx_run_algorithm(struct target *target, struct reg *reg = register_get_by_name(dsp563xx->core_cache, reg_params[i].reg_name, - 0); + false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); continue; diff --git a/src/target/mips32.c b/src/target/mips32.c index e1f2b2832..c82536931 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -473,7 +473,7 @@ int mips32_run_algorithm(struct target *target, int num_mem_params, if (reg_params[i].direction == PARAM_IN) continue; - struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0); + struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); @@ -507,7 +507,7 @@ int mips32_run_algorithm(struct target *target, int num_mem_params, for (int i = 0; i < num_reg_params; i++) { if (reg_params[i].direction != PARAM_OUT) { - struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0); + struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); return ERROR_COMMAND_SYNTAX_ERROR; diff --git a/src/target/nds32.c b/src/target/nds32.c index cc6e2da44..d524fc288 100644 --- a/src/target/nds32.c +++ b/src/target/nds32.c @@ -997,7 +997,7 @@ int nds32_arch_state(struct target *target) nds32->virtual_hosting ? ", virtual hosting" : ""); /* save pc value to pseudo register pc */ - struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1); + struct reg *reg = register_get_by_name(target->reg_cache, "pc", true); buf_set_u32(reg->value, 0, 32, value_pc); return ERROR_OK; diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 50535e266..37bc0cc90 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1704,7 +1704,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, } /* Save registers */ - struct reg *reg_pc = register_get_by_name(target->reg_cache, "pc", 1); + struct reg *reg_pc = register_get_by_name(target->reg_cache, "pc", true); if (!reg_pc || reg_pc->type->get(reg_pc) != ERROR_OK) return ERROR_FAIL; uint64_t saved_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size); @@ -1713,7 +1713,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, uint64_t saved_regs[32]; for (int i = 0; i < num_reg_params; i++) { LOG_DEBUG("save %s", reg_params[i].reg_name); - struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, 0); + struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, false); if (!r) { LOG_ERROR("Couldn't find register named '%s'", reg_params[i].reg_name); return ERROR_FAIL; @@ -1747,7 +1747,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, LOG_DEBUG("Disabling Interrupts"); struct reg *reg_mstatus = register_get_by_name(target->reg_cache, - "mstatus", 1); + "mstatus", true); if (!reg_mstatus) { LOG_ERROR("Couldn't find mstatus!"); return ERROR_FAIL; @@ -1828,7 +1828,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, for (int i = 0; i < num_reg_params; i++) { if (reg_params[i].direction == PARAM_IN || reg_params[i].direction == PARAM_IN_OUT) { - struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, 0); + struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, false); if (r->type->get(r) != ERROR_OK) { LOG_ERROR("get(%s) failed", r->name); return ERROR_FAIL; @@ -1836,7 +1836,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, buf_cpy(r->value, reg_params[i].value, reg_params[i].size); } LOG_DEBUG("restore %s", reg_params[i].reg_name); - struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, 0); + struct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, false); buf_set_u64(buf, 0, info->xlen[0], saved_regs[r->number]); if (r->type->set(r, buf) != ERROR_OK) { LOG_ERROR("set(%s) failed", r->name); diff --git a/src/target/stm8.c b/src/target/stm8.c index 00b524e31..a1653bc57 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -1876,7 +1876,7 @@ static int stm8_run_algorithm(struct target *target, int num_mem_params, continue; struct reg *reg = register_get_by_name(stm8->core_cache, - reg_params[i].reg_name, 0); + reg_params[i].reg_name, false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); @@ -1910,7 +1910,7 @@ static int stm8_run_algorithm(struct target *target, int num_mem_params, for (int i = 0; i < num_reg_params; i++) { if (reg_params[i].direction != PARAM_OUT) { struct reg *reg = register_get_by_name(stm8->core_cache, - reg_params[i].reg_name, 0); + reg_params[i].reg_name, false); if (!reg) { LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); diff --git a/src/target/target.c b/src/target/target.c index 450e231c6..dbc99b41c 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -2342,7 +2342,7 @@ int target_profiling_default(struct target *target, uint32_t *samples, uint32_t sample_count = 0; /* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */ - struct reg *reg = register_get_by_name(target->reg_cache, "pc", 1); + struct reg *reg = register_get_by_name(target->reg_cache, "pc", true); int retval = ERROR_OK; for (;;) { @@ -3134,7 +3134,7 @@ COMMAND_HANDLER(handle_reg_command) } } else { /* access a single register by its name */ - reg = register_get_by_name(target->reg_cache, CMD_ARGV[0], 1); + reg = register_get_by_name(target->reg_cache, CMD_ARGV[0], true); if (!reg) goto not_found; From cdb8b00122142c58d9a91e37fbef322f2c9e5d02 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sat, 5 Jun 2021 14:01:10 +0200 Subject: [PATCH 14/27] doc/openocd: Fix typo Change-Id: I8cf679190d6911de2dee181879c8895b55466835 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/6296 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 361ceb43f..7f486a9dd 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -11181,7 +11181,7 @@ should be passed in to the proc in question. @section Internal low-level Commands -By "low-level," we mean commands that a human would typically not +By "low-level", we mean commands that a human would typically not invoke directly. @itemize @bullet From 42a0bf3c360c1eae418223f0ab535b4d7accae83 Mon Sep 17 00:00:00 2001 From: "R. Diez" Date: Sun, 23 May 2021 12:18:36 +0200 Subject: [PATCH 15/27] Doc fix: echo writes to the log, and not to stdout Fixes bug #202 Change-Id: I855a1b8570af71379891634f405b4cc726917cb2 Signed-off-by: R. Diez Reviewed-on: http://openocd.zylin.com/6272 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 1 - src/helper/command.c | 1 - 2 files changed, 2 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 7f486a9dd..daf0a6aa1 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -8153,7 +8153,6 @@ file (which is normally the server's standard output). @deffn {Command} {echo} [-n] message Logs a message at "user" priority. -Output @var{message} to stdout. Option "-n" suppresses trailing newline. @example echo "Downloading kernel -- please wait" diff --git a/src/helper/command.c b/src/helper/command.c index 4be3abd74..8ea805bd9 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -1222,7 +1222,6 @@ static const struct command_registration command_builtin_handlers[] = { .handler = jim_echo, .mode = COMMAND_ANY, .help = "Logs a message at \"user\" priority. " - "Output message to stdout. " "Option \"-n\" suppresses trailing newline", .usage = "[-n] string", }, From af39ee607cd6ce6f3d809bd715892f2df1bf552a Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Fri, 19 Jan 2018 20:54:26 +1100 Subject: [PATCH 16/27] tcl: Add support for the Digilent Nexys Video board * https://store.digilentinc.com/nexys-video-artix-7-fpga-trainer-board-for-multimedia-applications/ * https://reference.digilentinc.com/_media/nexys-video:nexys_video_sch.pdf The Nexys Video board has FTDI FT2232 whose channel B is connected to Artix-7 FPGA's JTAG pins, and can be supported by OpenOCD's ftdi interface. Tested to be working fine on real hardware. Change-Id: I2996166dc8c2b6c08a9390958adfcdec8fc2bd37 Signed-off-by: Rohit Singh Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/4364 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/board/digilent_nexys_video.cfg | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tcl/board/digilent_nexys_video.cfg diff --git a/tcl/board/digilent_nexys_video.cfg b/tcl/board/digilent_nexys_video.cfg new file mode 100644 index 000000000..f171e2403 --- /dev/null +++ b/tcl/board/digilent_nexys_video.cfg @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Digilent Nexys Video with Xilinx Artix-7 FPGA +# https://reference.digilentinc.com/programmable-logic/nexys-video/start + +adapter driver ftdi +adapter speed 30000 + +ftdi_device_desc "Digilent USB Device" +ftdi_vid_pid 0x0403 0x6010 + +# channel 0 is dedicated for Digilent's DPTI Interface +# channel 1 is used for JTAG +ftdi_channel 1 + +# just TCK TDI TDO TMS, no reset +ftdi_layout_init 0x0088 0x008b +reset_config none + +# Enable sampling on falling edge for high JTAG speeds. +ftdi_tdo_sample_edge falling + +transport select jtag + +source [find cpld/xilinx-xc7.cfg] +source [find cpld/jtagspi.cfg] From 0ef5144c32ac60ddf3bb005deb3136015e42ae4f Mon Sep 17 00:00:00 2001 From: Jesse Sheridan Date: Wed, 16 Jun 2021 10:38:00 -0700 Subject: [PATCH 17/27] target/riscv: Implement get_gdb_arch() Change-Id: I5f4ab5243104df41031950682f688f2448a09b17 Signed-off-by: Jesse Sheridan Reviewed-on: http://openocd.zylin.com/6322 Tested-by: jenkins Reviewed-by: Tim Newsome Reviewed-by: Antonio Borneo --- src/target/riscv/riscv.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 37bc0cc90..4b0bac500 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1614,6 +1614,18 @@ static int riscv_write_memory(struct target *target, target_addr_t address, return tt->write_memory(target, address, size, count, buffer); } +const char *riscv_get_gdb_arch(struct target *target) +{ + switch (riscv_xlen(target)) { + case 32: + return "riscv:rv32"; + case 64: + return "riscv:rv64"; + } + LOG_ERROR("Unsupported xlen: %d", riscv_xlen(target)); + return NULL; +} + static int riscv_get_gdb_reg_list_internal(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class, bool read) @@ -2848,6 +2860,7 @@ struct target_type riscv_target = { .mmu = riscv_mmu, .virt2phys = riscv_virt2phys, + .get_gdb_arch = riscv_get_gdb_arch, .get_gdb_reg_list = riscv_get_gdb_reg_list, .get_gdb_reg_list_noread = riscv_get_gdb_reg_list_noread, From a38a0afd17d943b8bbc046f5fcfbf150871557a2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 12 Jun 2021 20:48:51 +0200 Subject: [PATCH 18/27] tcl/target: Select default boot core on Renesas R-Car Gen2/Gen3 On SMP Renesas R-Car Gen2/Gen3 systems, select the boot core as the default target using the 'targets' command. This way, the user can start debugging code running on the boot core without having to switch to the boot core by explicitly invoking 'targets' command first, since it is likely the debugged code will run on the boot core. Note that most of the code is already in place, it was just not used, so this is more of a fix to make the original intention work. Change-Id: I727808adce617c1d9ebd6ffa34f60f5882cdae60 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/6313 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/target/renesas_rcar_gen2.cfg | 3 +++ tcl/target/renesas_rcar_gen3.cfg | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tcl/target/renesas_rcar_gen2.cfg b/tcl/target/renesas_rcar_gen2.cfg index 91baa6c90..e51b37202 100644 --- a/tcl/target/renesas_rcar_gen2.cfg +++ b/tcl/target/renesas_rcar_gen2.cfg @@ -87,12 +87,14 @@ dap create $_DAPNAME -chain-position $_CHIPNAME.cpu set CA15_DBGBASE {0x800B0000 0x800B2000 0x800B4000 0x800B6000} set CA7_DBGBASE {0x800F0000 0x800F2000 0x800F4000 0x800F6000} +set _targets "" set smp_targets "" proc setup_ca {core_name dbgbase num boot} { global _CHIPNAME global _DAPNAME global smp_targets + global _targets for { set _core 0 } { $_core < $num } { incr _core } { set _TARGETNAME $_CHIPNAME.$core_name.$_core set _CTINAME $_TARGETNAME.cti @@ -123,3 +125,4 @@ if { [string equal $_boot_core CA15] } { source [find target/renesas_rcar_reset_common.cfg] eval "target smp $smp_targets" +targets $_targets diff --git a/tcl/target/renesas_rcar_gen3.cfg b/tcl/target/renesas_rcar_gen3.cfg index 5738d371c..36e654491 100644 --- a/tcl/target/renesas_rcar_gen3.cfg +++ b/tcl/target/renesas_rcar_gen3.cfg @@ -112,12 +112,14 @@ set CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000} set CR7_DBGBASE 0x80910000 set CR7_CTIBASE 0x80918000 +set _targets "" set smp_targets "" proc setup_a5x {core_name dbgbase ctibase num boot} { global _CHIPNAME global _DAPNAME global smp_targets + global _targets for { set _core 0 } { $_core < $num } { incr _core } { set _TARGETNAME $_CHIPNAME.$core_name.$_core set _CTINAME $_TARGETNAME.cti @@ -169,3 +171,4 @@ if { [string equal $_boot_core CA57] } { source [find target/renesas_rcar_reset_common.cfg] eval "target smp $smp_targets" +targets $_targets From 7c8a068a40ab81abf0938c3e091bf4e927a47bcd Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 30 May 2021 17:34:10 +0200 Subject: [PATCH 19/27] tcl/target: Add support for Renesas R8A779A0 V3U SoC The V3U SoC is unique in that it now has 8x CA76 and CR52, while the previous SoCs had CA57/CA53/CR7 . This can still be handled without too complex modifications to the gen3 configuration file, so add the logic to handle it there. Change-Id: I7ab33eacc1fd379d369988d3d6690d2e82346c7e Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/6314 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/target/renesas_rcar_gen3.cfg | 57 +++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/tcl/target/renesas_rcar_gen3.cfg b/tcl/target/renesas_rcar_gen3.cfg index 36e654491..334d25568 100644 --- a/tcl/target/renesas_rcar_gen3.cfg +++ b/tcl/target/renesas_rcar_gen3.cfg @@ -7,6 +7,7 @@ # H3: Cortex-A57 x 4, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step) # M3W: Cortex-A57 x 2, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step) # M3N: Cortex-A57 x 2, Cortex-R7 x 2 (Lock-Step) +# V3U: Cortex-A76 x 8, Cortex-R52 x2 (Lock-Step) # V3H: Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step) # V3M: Cortex-A53 x 2, Cortex-R7 x 2 (Lock-Step) # E3: Cortex-A53 x 1, Cortex-R7 x 2 (Lock-Step) @@ -24,6 +25,12 @@ if { [info exists SOC] } { set _soc H3 } +set _num_ca53 0 +set _num_ca57 0 +set _num_ca76 0 +set _num_cr52 0 +set _num_cr7 0 + # Set configuration for each SOC and the default 'BOOT_CORE' switch $_soc { H3 { @@ -75,6 +82,12 @@ switch $_soc { set _num_cr7 0 set _boot_core CA53 } + V3U { + set _CHIPNAME r8a779a0 + set _num_ca76 8 + set _num_cr52 1 + set _boot_core CA76 + } default { error "'$_soc' is invalid!" } @@ -96,7 +109,7 @@ if { [info exists DAP_TAPID] } { set _DAP_TAPID 0x5ba00477 } -echo "\t$_soc - $_num_ca57 CA57(s), $_num_ca53 CA53(s), $_num_cr7 CR7(s)" +echo "\t$_soc - $_num_ca76 CA76(s), $_num_ca57 CA57(s), $_num_ca53 CA53(s), $_num_cr52 CR52(s), $_num_cr7 CR7(s)" echo "\tBoot Core - $_boot_core\n" set _DAPNAME $_CHIPNAME.dap @@ -105,10 +118,14 @@ set _DAPNAME $_CHIPNAME.dap jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID dap create $_DAPNAME -chain-position $_CHIPNAME.cpu +set CA76_DBGBASE {0x81410000 0x81510000 0x81610000 0x81710000 0x81c10000 0x81d10000 0x81e10000 0x81f10000} +set CA76_CTIBASE {0x81420000 0x81520000 0x81620000 0x81720000 0x81c20000 0x81d20000 0x81e20000 0x81f20000} set CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000} set CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000} set CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000} set CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000} +set CR52_DBGBASE 0x80c10000 +set CR52_CTIBASE 0x80c20000 set CR7_DBGBASE 0x80910000 set CR7_CTIBASE 0x80918000 @@ -137,33 +154,41 @@ proc setup_a5x {core_name dbgbase ctibase num boot} { } } -proc setup_cr7 {dbgbase ctibase boot} { +proc setup_cr7 {core_name dbgbase ctibase num boot} { global _CHIPNAME global _DAPNAME - set _TARGETNAME $_CHIPNAME.r7 - set _CTINAME $_TARGETNAME.cti - cti create $_CTINAME -dap $_DAPNAME -ap-num 1 -baseaddr $ctibase - set _command "target create $_TARGETNAME cortex_r4 -dap $_DAPNAME \ - -ap-num 1 -dbgbase $dbgbase" - if { $boot == 1 } { - set _targets "$_TARGETNAME" - } else { - set _command "$_command -defer-examine" + for { set _core 0 } { $_core < $num } { incr _core } { + set _TARGETNAME $_CHIPNAME.$core_name + set _CTINAME $_TARGETNAME.cti + cti create $_CTINAME -dap $_DAPNAME -ap-num 1 -baseaddr $ctibase + set _command "target create $_TARGETNAME cortex_r4 -dap $_DAPNAME \ + -ap-num 1 -dbgbase $dbgbase" + if { $boot == 1 } { + set _targets "$_TARGETNAME" + } else { + set _command "$_command -defer-examine" + } + eval $_command } - eval $_command } # Organize target list based on the boot core -if { [string equal $_boot_core CA57] } { +if { [string equal $_boot_core CA76] } { + setup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 1 + setup_cr7 r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 0 +} elseif { [string equal $_boot_core CA57] } { setup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1 setup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0 - setup_cr7 $CR7_DBGBASE $CR7_CTIBASE 0 + setup_cr7 r7 $CR7_DBGBASE $CR7_CTIBASE $_num_cr7 0 } elseif { [string equal $_boot_core CA53] } { setup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1 setup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0 - setup_cr7 $CR7_DBGBASE $CR7_CTIBASE 0 + setup_cr7 r7 $CR7_DBGBASE $CR7_CTIBASE $_num_cr7 0 +} elseif { [string equal $_boot_core CR52] } { + setup_cr7 r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 1 + setup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 0 } else { - setup_cr7 $CR7_DBGBASE $CR7_CTIBASE 1 + setup_cr7 r7 $CR7_DBGBASE $CR7_CTIBASE $_num_cr7 1 setup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0 setup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0 } From fb34fd60ca955fe05c31357052aefad5fa1ef08f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 12 Jun 2021 20:19:30 +0200 Subject: [PATCH 20/27] tcl/board: Add Renesas Falcon board Add board configuration for Renesas Falcon board based on the R8A779A0 V3U SoC. Change-Id: If8369f2e2b97dfea9ccbee2c9b916ef7094f9b92 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/6315 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/board/renesas_falcon.cfg | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tcl/board/renesas_falcon.cfg diff --git a/tcl/board/renesas_falcon.cfg b/tcl/board/renesas_falcon.cfg new file mode 100644 index 000000000..c796f85b5 --- /dev/null +++ b/tcl/board/renesas_falcon.cfg @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Renesas R-Car V3U Falcon Board Config + +# The Falcon board comes with either an V3U SOC. + +echo "\nFalcon:" +if { ![info exists SOC] } { + set SOC V3U +} +source [find target/renesas_rcar_gen3.cfg] From 56b72b33cfc7014e001fa9e209b62f4b6c009fb5 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 17 Jun 2021 15:47:11 +0200 Subject: [PATCH 21/27] target/dsp563xx: Handle return values This fixes 'dead assignment' bugs identified by the clang static analyzer. Change-Id: I140ed55f0043e06a533f45f50a36887614585b04 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/6323 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/dsp563xx.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c index 81ea21e81..730573347 100644 --- a/src/target/dsp563xx.c +++ b/src/target/dsp563xx.c @@ -1085,8 +1085,17 @@ static int dsp563xx_poll(struct target *target) if (!dsp563xx->hardware_breakpoints_cleared) { err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0); + if (err != ERROR_OK) + return err; + err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, 0); + if (err != ERROR_OK) + return err; + err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0); + if (err != ERROR_OK) + return err; + dsp563xx->hardware_breakpoints_cleared = 1; } From 873e5c3976eb82589d5a645266b6ae75cb4c2ecf Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 17 Jun 2021 15:50:47 +0200 Subject: [PATCH 22/27] target/dsp563xx: Use bool data type for 'hardware_breakpoints_cleared' Change-Id: Ic18973d3e90d74c211b48627bdaac4cf3357b682 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/6324 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/dsp563xx.c | 4 ++-- src/target/dsp563xx.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c index 730573347..5ad52b58d 100644 --- a/src/target/dsp563xx.c +++ b/src/target/dsp563xx.c @@ -913,7 +913,7 @@ static int dsp563xx_init_target(struct command_context *cmd_ctx, struct target * dsp563xx_build_reg_cache(target); struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target); - dsp563xx->hardware_breakpoints_cleared = 0; + dsp563xx->hardware_breakpoints_cleared = false; dsp563xx->hardware_breakpoint[0].used = BPU_NONE; return ERROR_OK; @@ -1096,7 +1096,7 @@ static int dsp563xx_poll(struct target *target) if (err != ERROR_OK) return err; - dsp563xx->hardware_breakpoints_cleared = 1; + dsp563xx->hardware_breakpoints_cleared = true; } return ERROR_OK; diff --git a/src/target/dsp563xx.h b/src/target/dsp563xx.h index 18428b854..5c3e1d3c7 100644 --- a/src/target/dsp563xx.h +++ b/src/target/dsp563xx.h @@ -52,7 +52,7 @@ struct dsp563xx_common { struct hardware_breakpoint hardware_breakpoint[1]; /*Were the hardware breakpoints cleared on startup?*/ - int hardware_breakpoints_cleared; + bool hardware_breakpoints_cleared; }; struct dsp563xx_core_reg { From 2044df3dac715e5bf03a2ebac87048f808d1c7b1 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 14 Nov 2020 16:38:38 +0100 Subject: [PATCH 23/27] armv7m: replace flag 'stlink' with 'is_hla_target' The HLA target is not anymore used by ST-Link only, but required by Nu-Link and TI-ICDI too. Rename the flag 'stlink' as 'is_hla_target'. Change-Id: Id2ee2c0a1e8bf1f1e899f7a560140c34eefeeee5 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/6206 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/target/armv7m.h | 4 ++-- src/target/cortex_m.c | 6 +++--- src/target/hla_target.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/target/armv7m.h b/src/target/armv7m.h index f3445e152..f3eb90f24 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -239,8 +239,8 @@ struct armv7m_common { int fp_feature; uint32_t demcr; - /* stlink is a high level adapter, does not support all functions */ - bool stlink; + /* hla_target uses a high level adapter that does not support all functions */ + bool is_hla_target; struct armv7m_trace_config trace_config; diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index d0256b134..c30556c8a 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2031,9 +2031,9 @@ int cortex_m_examine(struct target *target) struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap; struct armv7m_common *armv7m = target_to_armv7m(target); - /* stlink shares the examine handler but does not support + /* hla_target shares the examine handler but does not support * all its calls */ - if (!armv7m->stlink) { + if (!armv7m->is_hla_target) { if (cortex_m->apsel == DP_APSEL_INVALID) { /* Search for the MEM-AP */ retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap); @@ -2127,7 +2127,7 @@ int cortex_m_examine(struct target *target) 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 (!armv7m->is_hla_target) { if (cortex_m->core_info->flags & CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K) /* Cortex-M3/M4 have 4096 bytes autoincrement range, * s. ARM IHI 0031C: MEM-AP 7.2.2 */ diff --git a/src/target/hla_target.c b/src/target/hla_target.c index cd57dd207..7688927fe 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -179,7 +179,7 @@ static int adapter_init_arch_info(struct target *target, armv7m->store_core_reg_u32 = adapter_store_core_reg_u32; armv7m->examine_debug_reason = adapter_examine_debug_reason; - armv7m->stlink = true; + armv7m->is_hla_target = true; target_register_timer_callback(hl_handle_target_request, 1, TARGET_TIMER_TYPE_PERIODIC, target); From 0478a93ed52fd8ddc0f68434cb2f05f22cbcad70 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Tue, 15 Jun 2021 16:49:37 +0200 Subject: [PATCH 24/27] target/breakpoints: Remove dead code and cleanup Change-Id: I8027178b6e771753775514a8641a050c6e63a1d5 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/6321 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/breakpoints.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index c060c7cde..dc8f3c573 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -50,11 +50,8 @@ static int breakpoint_add_internal(struct target *target, struct breakpoint **breakpoint_p = &target->breakpoints; const char *reason; int retval; - int n; - n = 0; while (breakpoint) { - n++; if (breakpoint->address == address) { /* FIXME don't assume "same address" means "same * breakpoint" ... check all the parameters before @@ -114,11 +111,8 @@ static int context_breakpoint_add_internal(struct target *target, struct breakpoint *breakpoint = target->breakpoints; struct breakpoint **breakpoint_p = &target->breakpoints; int retval; - int n; - n = 0; while (breakpoint) { - n++; if (breakpoint->asid == asid) { /* FIXME don't assume "same address" means "same * breakpoint" ... check all the parameters before @@ -167,10 +161,8 @@ static int hybrid_breakpoint_add_internal(struct target *target, struct breakpoint *breakpoint = target->breakpoints; struct breakpoint **breakpoint_p = &target->breakpoints; int retval; - int n; - n = 0; + while (breakpoint) { - n++; if ((breakpoint->asid == asid) && (breakpoint->address == address)) { /* FIXME don't assume "same address" means "same * breakpoint" ... check all the parameters before @@ -238,8 +230,9 @@ int breakpoint_add(struct target *target, head = head->next; } return retval; - } else + } else { return breakpoint_add_internal(target, address, length, type); + } } int context_breakpoint_add(struct target *target, @@ -260,8 +253,9 @@ int context_breakpoint_add(struct target *target, head = head->next; } return retval; - } else + } else { return context_breakpoint_add_internal(target, asid, length, type); + } } int hybrid_breakpoint_add(struct target *target, @@ -301,7 +295,7 @@ static void breakpoint_free(struct target *target, struct breakpoint *breakpoint breakpoint = breakpoint->next; } - if (breakpoint == NULL) + if (!breakpoint) return; retval = target_remove_breakpoint(target, breakpoint); @@ -346,20 +340,21 @@ static void breakpoint_remove_all_internal(struct target *target) void breakpoint_remove(struct target *target, target_addr_t address) { - int found = 0; if (target->smp) { + unsigned int num_breakpoints = 0; struct target_list *head; struct target *curr; head = target->head; while (head != (struct target_list *)NULL) { curr = head->target; - found += breakpoint_remove_internal(curr, address); + num_breakpoints += breakpoint_remove_internal(curr, address); head = head->next; } - if (found == 0) + if (!num_breakpoints) LOG_ERROR("no breakpoint at address " TARGET_ADDR_FMT " found", address); - } else + } else { breakpoint_remove_internal(target, address); + } } void breakpoint_remove_all(struct target *target) @@ -397,9 +392,9 @@ void breakpoint_clear_target(struct target *target) breakpoint_clear_target_internal(curr); head = head->next; } - } else + } else { breakpoint_clear_target_internal(target); - + } } struct breakpoint *breakpoint_find(struct target *target, target_addr_t address) @@ -494,7 +489,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint watchpoint = watchpoint->next; } - if (watchpoint == NULL) + if (!watchpoint) return; retval = target_remove_watchpoint(target, watchpoint); LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval); From 94ba5219ede27d6193ebac15af0468de60c9bfca Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Mon, 21 Jun 2021 16:18:38 +0200 Subject: [PATCH 25/27] flash/nor/stm32l4: Fix stm32l4_probe() The current implementation fails due to the assert() statements in get_stm32l4_rev_str() and get_stm32l4_bank_type_str(). Rearrange the code in order to fix the problem. Change-Id: If19c648dec8ddd3ef2fb801150114104b34c3bf2 Signed-off-by: Marc Schink Fixes: 64c2e03b23 ("flash/nor: improved API of flash_driver.info & fixed buffer overruns") Reviewed-on: http://openocd.zylin.com/6326 Tested-by: jenkins Reviewed-by: Jan Matyas Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- src/flash/nor/stm32l4x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index cd6229548..9598345c6 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -1350,7 +1350,6 @@ static const char *get_stm32l4_bank_type_str(struct flash_bank *bank) { struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; assert(stm32l4_info->part_info); - assert(stm32l4_info->probed); return stm32l4_is_otp(bank) ? "OTP" : stm32l4_info->dual_bank_mode ? "Flash dual" : "Flash single"; @@ -1372,8 +1371,6 @@ static int stm32l4_probe(struct flash_bank *bank) return retval; const uint32_t device_id = stm32l4_info->idcode & 0xFFF; - const uint16_t rev_id = stm32l4_info->idcode >> 16; - const char *rev_str = get_stm32l4_rev_str(bank); for (unsigned int n = 0; n < ARRAY_SIZE(stm32l4_parts); n++) { if (device_id == stm32l4_parts[n].id) { @@ -1388,12 +1385,15 @@ static int stm32l4_probe(struct flash_bank *bank) } part_info = stm32l4_info->part_info; - stm32l4_info->flash_regs = stm32l4_info->part_info->default_flash_regs; + const char *rev_str = get_stm32l4_rev_str(bank); + const uint16_t rev_id = stm32l4_info->idcode >> 16; LOG_INFO("device idcode = 0x%08" PRIx32 " (%s - Rev %s : 0x%04x - %s-bank)", stm32l4_info->idcode, part_info->device_str, rev_str, rev_id, get_stm32l4_bank_type_str(bank)); + stm32l4_info->flash_regs = stm32l4_info->part_info->default_flash_regs; + /* read flash option register */ retval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_OPTR_INDEX, &options); if (retval != ERROR_OK) From cff0e417da58adef1ceef9a63a99412c2cc87ff3 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 23 Jun 2021 16:52:16 +0200 Subject: [PATCH 26/27] stlink: fix SIGSEGV with libusb v1.0.24-33-g32a2206 (11618) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stlink driver incorrectly uses a NULL pointer for libusb's struct libusb_context. The correct value to be used is local in libusb_helper.c. Move in the helper file, in a wrapper function, the only call that requires the above value, and let stlink driver to use this wrapper. This issue has not triggered any visible problem until a code refactoring [1] in libusb has made OpenOCD crashing on Windows and on MacOS. Change-Id: Id1818c8af7cf0d4d17dfa1d22aad079da01ef740 Signed-off-by: Antonio Borneo Fixes: https://sourceforge.net/p/openocd/tickets/308/ Fixes: https://github.com/libusb/libusb/issues/928/ Fixes: 42d8fa899c6a ("stlink_usb: Submit multiple USB URBs at once to improve performance") Link: [1] https://github.com/libusb/libusb/commit/32a22069428c Reported-by: Andrzej Sierżęga Co-developed-by: Andrzej Sierżęga Co-developed-by: Xiaofan Chen Reviewed-on: http://openocd.zylin.com/6331 Tested-by: jenkins Reviewed-by: Marc Schink Reviewed-by: Xiaofan Reviewed-by: Andrzej Sierżęga Reviewed-by: Oleksij Rempel Reviewed-by: Andreas Fritiofson --- src/jtag/drivers/libusb_helper.c | 5 +++++ src/jtag/drivers/libusb_helper.h | 1 + src/jtag/drivers/stlink_usb.c | 7 +------ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c index f0122d534..18fe4bad4 100644 --- a/src/jtag/drivers/libusb_helper.c +++ b/src/jtag/drivers/libusb_helper.c @@ -363,3 +363,8 @@ int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid) return ERROR_FAIL; } + +int jtag_libusb_handle_events_completed(int *completed) +{ + return libusb_handle_events_completed(jtag_libusb_context, completed); +} diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h index fa7d06e28..3e77865d6 100644 --- a/src/jtag/drivers/libusb_helper.h +++ b/src/jtag/drivers/libusb_helper.h @@ -60,5 +60,6 @@ int jtag_libusb_choose_interface(struct libusb_device_handle *devh, unsigned int *usb_write_ep, int bclass, int subclass, int protocol, int trans_type); int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid); +int jtag_libusb_handle_events_completed(int *completed); #endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H */ diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index c68bbb3ca..7b1932b9f 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -497,13 +497,8 @@ static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer) { int r, *completed = transfer->user_data; - /* Assuming a single libusb context exists. There no existing interface into this - * module to pass a libusb context. - */ - struct libusb_context *ctx = NULL; - while (!*completed) { - r = libusb_handle_events_completed(ctx, completed); + r = jtag_libusb_handle_events_completed(completed); if (r < 0) { if (r == LIBUSB_ERROR_INTERRUPTED) continue; From c10422f0fa263021942e2461d0d9f2dd30c44b18 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Wed, 30 Jun 2021 15:01:45 -0700 Subject: [PATCH 27/27] Fix build. Change-Id: Ib8a1d0ad66a74b4bc85fd70b4cd82d1ccc200e56 Signed-off-by: Tim Newsome --- src/flash/nor/gd32vf103.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/flash/nor/gd32vf103.c b/src/flash/nor/gd32vf103.c index 96c08f97f..562f41e7b 100644 --- a/src/flash/nor/gd32vf103.c +++ b/src/flash/nor/gd32vf103.c @@ -110,7 +110,7 @@ struct gd32vf103_flash_bank { }; static int gd32vf103_mass_erase(struct flash_bank *bank); -static int get_gd32vf103_info(struct flash_bank *bank, char *buf, int buf_size); +static int get_gd32vf103_info(struct flash_bank *bank, struct command_invocation *cmd); static int gd32vf103_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count); @@ -931,7 +931,7 @@ static int gd32vf103_auto_probe(struct flash_bank *bank) return gd32vf103_probe(bank); } -static int get_gd32vf103_info(struct flash_bank *bank, char *buf, int buf_size) +static int get_gd32vf103_info(struct flash_bank *bank, struct command_invocation *cmd) { uint32_t dbgmcu_idcode; @@ -961,14 +961,14 @@ static int get_gd32vf103_info(struct flash_bank *bank, char *buf, int buf_size) } break; default: - snprintf(buf, buf_size, "Cannot identify target as a GD32VF103 x\n"); + command_print_sameline(cmd, "Cannot identify target as a GD32VF103 x\n"); return ERROR_FAIL; } if (rev_str != NULL) - snprintf(buf, buf_size, "%s - Rev: %s", device_str, rev_str); + command_print_sameline(cmd, "%s - Rev: %s\n", device_str, rev_str); else - snprintf(buf, buf_size, "%s - Rev: unknown (0x%04x)", device_str, rev_id); + command_print_sameline(cmd, "%s - Rev: unknown (0x%04x)\n", device_str, rev_id); return ERROR_OK; }