From 71013521d7b195022616284aabc5e072a60c52bf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 3 May 2024 23:04:46 +0200 Subject: [PATCH 01/47] server: gdb: respect command gdb_report_register_access_error Commit 236c54c94a53 ("server/gdb_server.c: support unavailable registers") correctly returns a string of 'x' when the register is not available in the current target. While implementing this, it incorrectly drops the pre-existing feature of optionally ignoring errors while reading a register. This feature has a real use case documented in the OpenOCD manual in chapter 'Using GDB as a non-intrusive memory inspector', where GDB attaches to a target without halting it. For targets that need to be halted to read its registers, we need to hack the values of the registers returned to GDB; either returning 'xxxx' or an error causes GDB to drop the connection. Re-add the check on 'gdb_report_register_access_error' to keep the pre-existing behavior when a register error has to be ignored: - return a string of '0'; - drop a debug message. Change-Id: Ie65c92f259f92502e688914f334655b635874179 Signed-off-by: Antonio Borneo Fixes: 236c54c94a53 ("server/gdb_server.c: support unavailable registers") Reviewed-on: https://review.openocd.org/c/openocd/+/8228 Tested-by: jenkins --- src/server/gdb_server.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 5052bf43b..7c2f41e41 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1233,6 +1233,8 @@ static int gdb_get_reg_value_as_str(struct target *target, char *tstr, struct re tstr[len] = '\0'; return ERROR_OK; } + memset(tstr, '0', len); + tstr[len] = '\0'; return ERROR_FAIL; } @@ -1277,7 +1279,9 @@ static int gdb_get_registers_packet(struct connection *connection, for (i = 0; i < reg_list_size; i++) { if (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden) continue; - if (gdb_get_reg_value_as_str(target, reg_packet_p, reg_list[i]) != ERROR_OK) { + retval = gdb_get_reg_value_as_str(target, reg_packet_p, reg_list[i]); + if (retval != ERROR_OK && gdb_report_register_access_error) { + LOG_DEBUG("Couldn't get register %s.", reg_list[i]->name); free(reg_packet); free(reg_list); return gdb_error(connection, retval); @@ -1395,7 +1399,9 @@ static int gdb_get_register_packet(struct connection *connection, reg_packet = calloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2 + 1, 1); /* plus one for string termination null */ - if (gdb_get_reg_value_as_str(target, reg_packet, reg_list[reg_num]) != ERROR_OK) { + retval = gdb_get_reg_value_as_str(target, reg_packet, reg_list[reg_num]); + if (retval != ERROR_OK && gdb_report_register_access_error) { + LOG_DEBUG("Couldn't get register %s.", reg_list[reg_num]->name); free(reg_packet); free(reg_list); return gdb_error(connection, retval); From c7c4d4d48c63c1048414779f633641ea4e9657c8 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Mon, 20 May 2024 11:32:19 +0200 Subject: [PATCH 02/47] contrib: Drop 'coresight-trace.txt' This document is outdated and has broken text formatting. It also provides no useful information to users nor developers, at worst it causes confusion. For that reason, drop this file. Change-Id: Id5ee1f6e74d1a641c60d897f114bb97f5fd48e5b Signed-off-by: Marc Schink Reviewed-on: https://review.openocd.org/c/openocd/+/8292 Tested-by: jenkins Reviewed-by: Antonio Borneo --- contrib/coresight-trace.txt | 68 ------------------------------------- 1 file changed, 68 deletions(-) delete mode 100644 contrib/coresight-trace.txt diff --git a/contrib/coresight-trace.txt b/contrib/coresight-trace.txt deleted file mode 100644 index 517119b6f..000000000 --- a/contrib/coresight-trace.txt +++ /dev/null @@ -1,68 +0,0 @@ -+OpenOCD and CoreSight Tracing -+ -Many recent ARM chips (Using e..g. Cortex-M3 and -Cortex-M4 cores) support CoreSight debug/trace. -This note sketches an approach currently planned for those cores -with OpenOCD. - - This tracing data can help debug and tune ARM software, but not -all cores support tracing. Some support more extensive tracing -other cores with trace support +should be able to use the same -approach and maybe some of the same analysis code. - -+the Cortex-M3 is assumed here to be the -+core in use, for simplicity and to reflect current OpenOCD users. - - -This note summarizes a software model to generate, collect, and -analyze such trace data . That is not fully implemented as of early -January 2011, +and thus is not *yet* usable. -+ -+ -+Some microcontroller cores support a low pin-count Single-wire trace, -with a mode where +trace data is emitted (usually to a UART. To use -this mode, +SWD must be in use. -+At this writing, OpenOCD SWD support is not yet complete either. - -(There are also multi-wire trace ports requiring more complex debug -adapters than OpenOCD currently supports, and offering richer data. -+ -+ -+* ENABLING involves activating SWD and (single wire) trace. -+ -+current expectations are that OpenOCD itself will handle enabling; -activating single wire trace involves a debug adapter interaction, and -collecting that trace data requires particular (re)wiring. -+ -+* CONFIGURATION involves setting up ITM and/or ETM modules to emit the -+desired data from the Cortex core. (This might include dumping -+event counters printf-style messages; code profiling; and more. Not all -+cores offer the same trace capabilities. -+ -+current expectations are that Tcl scripts will be used to configure these -+modules for the desired tracing, by direct writes to registers. In some -+cases (as with RTOS event tracking and similar messaging, this might -+be augmented or replaced by user code running on the ARM core. -+ -+COLLECTION involves reading that trace data, probably through UART, and -+saving it in a useful format to analyse For now, deferred analysis modes -are assumed, not than real-time or interactive ones. -+ -+ -+current expectations are to to dump data in text using contrib/itmdump.c -+or derived tools, and to post-process it into reports. Such reports might -+include program messaging (such as application data streams via ITM, maybe -+using printf type messaging; code coverage analysis or so forth. Recent -+versions of CMSIS software reserve some ITM codespace for RTOS event -tracing and include ITM messaging support. -Clearly some of that data would be valuable for interactive debugging. -+ -+Should someone get ambitious, GUI reports should be possible. GNU tools -+for simpler reports like gprof may be simpler to support at first. -+In any case, OpenOCD is not currently GUI-oriented. Accordingly, we now -+expect any such graphics to come from postprocessing. - - measurements for RTOS event timings should also be easy to collect. -+Examples include context and message switch times, as well as times -for application interactions. -+ From eecba412cd8a6d515c925d87fe53e79881305517 Mon Sep 17 00:00:00 2001 From: Noah Moroze Date: Wed, 15 May 2024 22:39:12 -0400 Subject: [PATCH 03/47] tcl/memory: fix syntax errors Using a command in an expression requires a bracketed command substitution. These syntax errors were caught by tclint v0.2.5 (https://github.com/nmoroze/tclint): ``` tclint tcl/memory.tcl | grep "syntax error" ``` Change-Id: I510d46222f4fb02d6ef73121b231d5b2df77e5c0 Signed-off-by: Noah Moroze Reviewed-on: https://review.openocd.org/c/openocd/+/8279 Reviewed-by: Antonio Borneo Tested-by: jenkins --- tcl/memory.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcl/memory.tcl b/tcl/memory.tcl index b11174995..8b93b515e 100644 --- a/tcl/memory.tcl +++ b/tcl/memory.tcl @@ -66,10 +66,10 @@ proc iswithin { ADDRESS BASE LEN } { proc address_info { ADDRESS } { foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } { - if { info exists $WHERE } { + if { [info exists $WHERE] } { set lmt [set N_[set WHERE]] for { set region 0 } { $region < $lmt } { incr region } { - if { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } { + if { [iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN)] } { return "$WHERE $region"; } } From 223e3d8fe76d86f01111bbe37f83a19d719ac81a Mon Sep 17 00:00:00 2001 From: Noah Moroze Date: Wed, 15 May 2024 22:47:53 -0400 Subject: [PATCH 04/47] tcl/target/c100helper: fix syntax errors Fixes: 64d89d5ee1a5 ("tcl: [3/3] prepare for jimtcl 0.81 'expr' syntax change") These syntax errors were caught by tclint v0.2.5 (https://github.com/nmoroze/tclint): ``` tclint tcl/target/c100helper.tcl | grep "syntax error" ``` Change-Id: I511c54353c4853560adca6b4852d48df2aade283 Signed-off-by: Noah Moroze Reviewed-on: https://review.openocd.org/c/openocd/+/8280 Reviewed-by: Antonio Borneo Tested-by: jenkins --- tcl/target/c100helper.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcl/target/c100helper.tcl b/tcl/target/c100helper.tcl index d1d3f258b..ba0e4fe0a 100644 --- a/tcl/target/c100helper.tcl +++ b/tcl/target/c100helper.tcl @@ -176,7 +176,7 @@ proc setupAmbaClk {} { mmw $CLKCORE_AHB_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0 # wait for PLL to lock echo "Waiting for Amba PLL to lock" - while {[expr {[mrw $CLKCORE_PLL_STATUS] & $AHBCLK_PLL_LOCK]} == 0} { sleep 1 } + while {[mrw $CLKCORE_PLL_STATUS] & $AHBCLK_PLL_LOCK == 0} { sleep 1 } # remove the internal PLL bypass mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $AHB_PLL_BY_CTRL # remove PLL from BYPASS mode using MUX @@ -250,7 +250,7 @@ proc setupArmClk {} { mmw $CLKCORE_ARM_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0 # wait for PLL to lock echo "Waiting for Amba PLL to lock" - while {[expr {[mrw $CLKCORE_PLL_STATUS] & $FCLK_PLL_LOCK]} == 0} { sleep 1 } + while {[mrw $CLKCORE_PLL_STATUS] & $FCLK_PLL_LOCK == 0} { sleep 1 } # remove the internal PLL bypass mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $ARM_PLL_BY_CTRL # remove PLL from BYPASS mode using MUX From 7050cade9dcea77dd9882669ea97fddc6a8084d4 Mon Sep 17 00:00:00 2001 From: Noah Moroze Date: Wed, 15 May 2024 22:49:23 -0400 Subject: [PATCH 05/47] tcl/chip/st/spear: fix syntax errors While the current jimtcl does not consider this an error, the Tcl dodekalogue states that strings terminate at the second double quote character (see https://www.tcl.tk/man/tcl/TclCmd/Tcl.htm#M8). These syntax errors were caught by tclint v0.2.5 (https://github.com/nmoroze/tclint): ``` tclint tcl/chip/st/spear/spear3xx_ddr.tcl | grep "syntax error" ``` Change-Id: I2763d93095e3db7590644652f16b7b24939d6cae Signed-off-by: Noah Moroze Reviewed-on: https://review.openocd.org/c/openocd/+/8281 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Antonio Borneo --- tcl/chip/st/spear/spear3xx_ddr.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcl/chip/st/spear/spear3xx_ddr.tcl b/tcl/chip/st/spear/spear3xx_ddr.tcl index 59925672d..06962215b 100644 --- a/tcl/chip/st/spear/spear3xx_ddr.tcl +++ b/tcl/chip/st/spear/spear3xx_ddr.tcl @@ -10,7 +10,7 @@ proc sp3xx_ddr_init {ddr_type {ddr_chips 1}} { if { $ddr_chips != 1 && $ddr_chips != 2 } { - error "Only 1 or 2 DDR chips permitted. Wrong value "$ddr_chips + error "Only 1 or 2 DDR chips permitted. Wrong value $ddr_chips" } if { $ddr_type == "mt47h64m16_3_333_cl5_async" } { @@ -21,7 +21,7 @@ proc sp3xx_ddr_init {ddr_type {ddr_chips 1}} { # ????? $ddr_chips # set ddr_size 0x????? } else { - error "sp3xx_ddr_init: unrecognized DDR type "$ddr_type + error "sp3xx_ddr_init: unrecognized DDR type $ddr_type" } # MPMC START From b5e7118048250a4ffc589fd8b82a11de05132d23 Mon Sep 17 00:00:00 2001 From: Noah Moroze Date: Wed, 15 May 2024 22:50:58 -0400 Subject: [PATCH 06/47] src/helper/startup: fix syntax errors The missing closing brackets were caught by tclint v0.2.5 (https://github.com/nmoroze/tclint): ``` tclint src/helper/startup.tcl | grep "syntax error" ``` The improperly escaped backslash was caught by manual inspection during code review. Change-Id: I8cd44e58040d4627f6b2fc8b88ca8a930cda0ba6 Signed-off-by: Noah Moroze Reviewed-on: https://review.openocd.org/c/openocd/+/8282 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/helper/startup.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl index 5a0d479f5..e6e76e68f 100644 --- a/src/helper/startup.tcl +++ b/src/helper/startup.tcl @@ -11,10 +11,10 @@ proc find {filename} { if {[catch {ocd_find $filename} t]==0} { return $t } - if {[catch {ocd_find [string map {\ /} $filename} t]==0} { + if {[catch {ocd_find [string map {\\ /} $filename]} t]==0} { return $t } - if {[catch {ocd_find [string map {/ \\} $filename} t]==0} { + if {[catch {ocd_find [string map {/ \\} $filename]} t]==0} { return $t } # make sure error message matches original input string From 72b39088ee1772a65e74004fdc096db09edf8c0c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 8 Apr 2024 17:42:52 +0200 Subject: [PATCH 07/47] target: reset examine after assert_reset For some target, the API assert_reset() checks if the target has been examined, with target_was_examined(), to perform conditional operations like: - assert adapter's srst; - write some register to catch the reset vector; - invalidate the register cache. Targets created with -defer-examine gets the examine flag reset right before entering in their assert_reset(), disrupting the actions above. For targets created with -defer-examine, move the reset examine after the assert_reset(). Change-Id: If96e7876dcace8905165115292deb93a3e45cb36 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8293 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/target.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index efc168903..7d4947a6e 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5365,17 +5365,19 @@ COMMAND_HANDLER(handle_target_reset) return ERROR_FAIL; } - if (target->defer_examine) - target_reset_examined(target); - /* determine if we should halt or not. */ target->reset_halt = (a != 0); /* When this happens - all workareas are invalid. */ target_free_all_working_areas_restore(target, 0); /* do the assert */ - if (n->value == NVP_ASSERT) - return target->type->assert_reset(target); + if (n->value == NVP_ASSERT) { + int retval = target->type->assert_reset(target); + if (target->defer_examine) + target_reset_examined(target); + return retval; + } + return target->type->deassert_reset(target); } From 9623069e8090fbbf80250836e82feaecdb65233e Mon Sep 17 00:00:00 2001 From: Mark Featherston Date: Thu, 23 May 2024 13:24:32 -0700 Subject: [PATCH 08/47] jtag/drivers/ftdi: Use command_print instead of LOG_USER for get_signal LOG_USER only outputs to user interfaces, but leaves no way to get the FTDI inputs over the RPC interface. Switch to command_print so this string goes to both logs and the RPC interface. Change-Id: I99024194b6687b88d354ef278aa25f372c862c22 Signed-off-by: Mark Featherston Reviewed-on: https://review.openocd.org/c/openocd/+/8294 Reviewed-by: Antonio Borneo Tested-by: jenkins Reviewed-by: zapb --- src/jtag/drivers/ftdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 58f83af59..661300506 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -852,7 +852,7 @@ COMMAND_HANDLER(ftdi_handle_get_signal_command) uint16_t sig_data = 0; sig = find_signal_by_name(CMD_ARGV[0]); if (!sig) { - LOG_ERROR("interface configuration doesn't define signal '%s'", CMD_ARGV[0]); + command_print(CMD, "interface configuration doesn't define signal '%s'", CMD_ARGV[0]); return ERROR_FAIL; } @@ -860,7 +860,7 @@ COMMAND_HANDLER(ftdi_handle_get_signal_command) if (ret != ERROR_OK) return ret; - LOG_USER("Signal %s = %#06x", sig->name, sig_data); + command_print(CMD, "%#06x", sig_data); return ERROR_OK; } From 2f8bb252ffb89cb2019f634230bc17b4dfccc75a Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 21 Sep 2020 14:10:27 -0700 Subject: [PATCH 09/47] doc: Minimally describe the BSCAN tunnel interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add minimal documentation for the BSCAN tunnel interface. This is based on Tim Newsome 's work on the RISC-V fork. Change-Id: I5e0cd6972cb90649670249765e9bb30c2847eea6 Signed-off-by: Tim Newsome Signed-off-by: Bernhard Rosenkränzer Reviewed-on: https://review.openocd.org/c/openocd/+/8297 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 5eef81e40..87e3650b4 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -11279,8 +11279,22 @@ and DBUS registers, respectively. @end deffn @deffn {Command} {riscv use_bscan_tunnel} value -Enable or disable use of a BSCAN tunnel to reach DM. Supply the width of -the DM transport TAP's instruction register to enable. Supply a value of 0 to disable. +Enable or disable use of a BSCAN tunnel to reach the Debug Module. Supply the +width of the DM transport TAP's instruction register to enable. Supply a +value of 0 to disable. + +This BSCAN tunnel interface is specific to SiFive IP. Anybody may implement +it, but currently there is no good documentation on it. In a nutshell, this +feature scans USER4 into a Xilinx TAP to select the tunnel device (assuming +hardware is present and it is hooked up to the Xilinx USER4 IR) and +encapsulates a tunneled scan directive into a DR scan into the Xilinx TAP. A +tunneled DR scan consists of: +@enumerate +@item 1 bit that selects IR when 0, or DR when 1 +@item 7 bits that encode the width of the desired tunneled scan +@item A width+1 stream of bits for the tunneled TDI. The plus one is because there is a one-clock skew between TDI of Xilinx chain and TDO from tunneled chain. +@item 3 bits of zero that the tunnel uses to go back to idle state. +@end enumerate @end deffn @deffn {Command} {riscv set_ebreakm} on|off From d382c95d57c0ad9ed2dcc83c95404babb7647708 Mon Sep 17 00:00:00 2001 From: Parshintsev Anatoly Date: Thu, 22 Jun 2023 19:28:52 +0300 Subject: [PATCH 10/47] target/riscv: support for smp group manipulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this functionality allows to query if a target belongs to some smp group and to dynamically turn on/off smp-specific behavior Change-Id: I67bafb1817c621a38ae4a2f55e12e4143e992c4e Signed-off-by: Parshintsev Anatoly Signed-off-by: Bernhard Rosenkränzer Reviewed-on: https://review.openocd.org/c/openocd/+/8296 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 12 ++++++++++++ src/target/riscv/riscv.c | 3 +++ 2 files changed, 15 insertions(+) diff --git a/doc/openocd.texi b/doc/openocd.texi index 87e3650b4..b782e0ba9 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -11278,6 +11278,18 @@ When utilizing version 0.11 of the RISC-V Debug Specification, and DBUS registers, respectively. @end deffn +@deffn {Command} {riscv smp} [on|off] +Display, enable or disable SMP handling mode. This command is needed only if +user wants to temporary @b{disable} SMP handling for an existing SMP group +(see @code{aarch64 smp} for additional information). To define an SMP +group the command @code{target smp} should be used. +@end deffn + +@deffn {Command} {riscv smp_gdb} [core_id] +Display/set the current core displayed in GDB. This is needed only if +@code{riscv smp} was used. +@end deffn + @deffn {Command} {riscv use_bscan_tunnel} value Enable or disable use of a BSCAN tunnel to reach the Debug Module. Supply the width of the DM transport TAP's instruction register to enable. Supply a diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 9cd4922d2..511a3c6c3 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -3049,6 +3049,9 @@ static const struct command_registration riscv_command_handlers[] = { .usage = "", .chain = semihosting_common_handlers }, + { + .chain = smp_command_handlers + }, COMMAND_REGISTRATION_DONE }; From 84126893ff9305060b7d481ebf50e8c7405d7eae Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sat, 25 May 2024 18:55:23 +0200 Subject: [PATCH 11/47] tcl/board: Add config for NXP FRDM-KV11Z Change-Id: I9cd497a085f8f9c7854ae3b96e60a73b3b050d0e Signed-off-by: Marc Schink Reviewed-on: https://review.openocd.org/c/openocd/+/8298 Reviewed-by: Antonio Borneo Tested-by: jenkins --- tcl/board/nxp/frdm-kv11z-jlink.cfg | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tcl/board/nxp/frdm-kv11z-jlink.cfg diff --git a/tcl/board/nxp/frdm-kv11z-jlink.cfg b/tcl/board/nxp/frdm-kv11z-jlink.cfg new file mode 100644 index 000000000..725a37b9e --- /dev/null +++ b/tcl/board/nxp/frdm-kv11z-jlink.cfg @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Configuration file for NXP FRDM-KV11Z development boards. +# +# This configuration file is only for FRDM-KV11Z development boards with the +# SEGGER J-Link OpenSDA firmware, see: +# https://www.segger.com/products/debug-probes/j-link/models/other-j-links/opensda-sda-v2/ + +source [find interface/jlink.cfg] + +# Set working area size to 16 KiB. +set WORKAREASIZE 0x4000 + +# Set the chip name. +set CHIPNAME kv11z + +transport select swd + +source [find target/kx.cfg] + +reset_config srst_only From 0a3217b8ff34043e6c59850e5d7667edf97ec447 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sat, 25 May 2024 18:57:10 +0200 Subject: [PATCH 12/47] tcl/board: Add config for NXP FRDM-KV31F Change-Id: I4d7cd1bcadd8159e4830107c2788708aef02add0 Signed-off-by: Marc Schink Reviewed-on: https://review.openocd.org/c/openocd/+/8299 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/board/nxp/frdm-kv31f-jlink.cfg | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tcl/board/nxp/frdm-kv31f-jlink.cfg diff --git a/tcl/board/nxp/frdm-kv31f-jlink.cfg b/tcl/board/nxp/frdm-kv31f-jlink.cfg new file mode 100644 index 000000000..e55a01cd7 --- /dev/null +++ b/tcl/board/nxp/frdm-kv31f-jlink.cfg @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Configuration file for NXP FRDM-KV31F development boards. +# +# This configuration file is only for FRDM-KV31F development boards with the +# SEGGER J-Link OpenSDA firmware, see: +# https://www.segger.com/products/debug-probes/j-link/models/other-j-links/opensda-sda-v2/ + +source [find interface/jlink.cfg] + +# Set working area size to 32 KiB. +set WORKAREASIZE 0x8000 + +# Set the chip name. +set CHIPNAME kv31f + +transport select swd + +source [find target/kx.cfg] + +reset_config srst_only From 1fba55a9b62118ac102c161bb8efcd2ceed379a1 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sat, 1 Jun 2024 10:41:29 +0200 Subject: [PATCH 13/47] flash/nor/tcl: Fix memory leak of flash bank name Change-Id: I54cd1ee479a0570ae849a71be47c82eebd1ae454 Signed-off-by: Marc Schink Reviewed-on: https://review.openocd.org/c/openocd/+/8303 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/flash/nor/tcl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 720fb60a1..6ac932be7 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -1298,6 +1298,7 @@ COMMAND_HANDLER(handle_flash_bank_command) if (retval != ERROR_OK) { LOG_ERROR("'%s' driver rejected flash bank at " TARGET_ADDR_FMT "; usage: %s", driver_name, c->base, driver->usage); + free(c->name); free(c); return retval; } From ed9203f4aaf3b4a28d5e28da2cdb1a52d9f7c408 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Thu, 25 Apr 2024 14:33:07 +0300 Subject: [PATCH 14/47] gdb_server: do not start multiple instances on "pipe" For configurations which include multiple targets and the "pipe" mode is requested only the first gdb_server instance should be enabled, otherwise GDB gets confusing replies, goes out of sync and the session fails in weird ways. Compile-tested only. Signed-off-by: Paul Fertser Change-Id: If8f13aa7b58e9b0dc6d5ae88cf75538b34cc1218 Reviewed-on: https://review.openocd.org/c/openocd/+/8222 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/server/gdb_server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 7c2f41e41..0ded8e440 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -3879,7 +3879,7 @@ static int gdb_target_add_one(struct target *target) return gdb_target_start(target, target->gdb_port_override); } - if (strcmp(gdb_port, "disabled") == 0) { + if (strcmp(gdb_port_next, "disabled") == 0) { LOG_INFO("gdb port disabled"); return ERROR_OK; } @@ -3908,6 +3908,8 @@ static int gdb_target_add_one(struct target *target) gdb_port_next = strdup("0"); } } + } else if (strcmp(gdb_port_next, "pipe") == 0) { + gdb_port_next = "disabled"; } } return retval; From 37f9485cef8b98aaed739c8140b3674441dc5876 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 21 Jan 2024 23:25:13 +0100 Subject: [PATCH 15/47] flash/nor/nrf5: introduce address maps Preparatory change before extending support to nRF53 and 91. While on it, rename nRF51 and 52 specific routines and constants. Change-Id: I46bc496cef5cbde46d6755a4b908c875351f6612 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/8110 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/nrf5.c | 239 +++++++++++++++++++++++++++---------------- 1 file changed, 153 insertions(+), 86 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index bf8c9da5f..b4a8e979e 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -19,8 +19,7 @@ #include #include -/* Both those values are constant across the current spectrum ofr nRF5 devices */ -#define WATCHDOG_REFRESH_REGISTER 0x40010600 +/* The refresh code is constant across the current spectrum of nRF5 devices */ #define WATCHDOG_REFRESH_VALUE 0x6e524635 enum { @@ -28,12 +27,9 @@ enum { }; enum nrf5_ficr_registers { - NRF5_FICR_BASE = 0x10000000, /* Factory Information Configuration Registers */ + NRF51_52_FICR_BASE = 0x10000000, /* Factory Information Configuration Registers */ -#define NRF5_FICR_REG(offset) (NRF5_FICR_BASE + offset) - - NRF5_FICR_CODEPAGESIZE = NRF5_FICR_REG(0x010), - NRF5_FICR_CODESIZE = NRF5_FICR_REG(0x014), +#define NRF5_FICR_REG(offset) (NRF51_52_FICR_BASE + (offset)) NRF51_FICR_CLENR0 = NRF5_FICR_REG(0x028), NRF51_FICR_PPFC = NRF5_FICR_REG(0x02C), @@ -42,39 +38,23 @@ enum nrf5_ficr_registers { NRF51_FICR_SIZERAMBLOCK1 = NRF5_FICR_REG(0x03C), NRF51_FICR_SIZERAMBLOCK2 = NRF5_FICR_REG(0x040), NRF51_FICR_SIZERAMBLOCK3 = NRF5_FICR_REG(0x044), - - /* CONFIGID is documented on nRF51 series only. - * On nRF52 is present but not documented */ - NRF5_FICR_CONFIGID = NRF5_FICR_REG(0x05C), - - /* Following registers are available on nRF52 and on nRF51 since rev 3 */ - NRF5_FICR_INFO_PART = NRF5_FICR_REG(0x100), - NRF5_FICR_INFO_VARIANT = NRF5_FICR_REG(0x104), - NRF5_FICR_INFO_PACKAGE = NRF5_FICR_REG(0x108), - NRF5_FICR_INFO_RAM = NRF5_FICR_REG(0x10C), - NRF5_FICR_INFO_FLASH = NRF5_FICR_REG(0x110), }; enum nrf5_uicr_registers { - NRF5_UICR_BASE = 0x10001000, /* User Information + NRF51_52_UICR_BASE = 0x10001000, /* User Information * Configuration Registers */ -#define NRF5_UICR_REG(offset) (NRF5_UICR_BASE + offset) +#define NRF5_UICR_REG(offset) (NRF51_52_UICR_BASE + (offset)) NRF51_UICR_CLENR0 = NRF5_UICR_REG(0x000), }; enum nrf5_nvmc_registers { - NRF5_NVMC_BASE = 0x4001E000, /* Non-Volatile Memory - * Controller Registers */ - -#define NRF5_NVMC_REG(offset) (NRF5_NVMC_BASE + offset) - - NRF5_NVMC_READY = NRF5_NVMC_REG(0x400), - NRF5_NVMC_CONFIG = NRF5_NVMC_REG(0x504), - NRF5_NVMC_ERASEPAGE = NRF5_NVMC_REG(0x508), - NRF5_NVMC_ERASEALL = NRF5_NVMC_REG(0x50C), - NRF5_NVMC_ERASEUICR = NRF5_NVMC_REG(0x514), + NRF5_NVMC_READY = 0x400, + NRF5_NVMC_CONFIG = 0x504, + NRF5_NVMC_ERASEPAGE = 0x508, + NRF5_NVMC_ERASEALL = 0x50C, + NRF5_NVMC_ERASEUICR = 0x514, NRF5_BPROT_BASE = 0x40000000, }; @@ -110,6 +90,28 @@ struct nrf5_device_spec { enum nrf5_features features; }; +/* FICR registers offsets */ +struct nrf5_ficr_map { + uint32_t codepagesize; + uint32_t codesize; + uint32_t configid; + uint32_t info_part; + uint32_t info_variant; + uint32_t info_package; + uint32_t info_ram; + uint32_t info_flash; +}; + +/* Map of device */ +struct nrf5_map { + uint32_t flash_base; + uint32_t ficr_base; + uint32_t uicr_base; + uint32_t nvmc_base; + + uint32_t watchdog_refresh_addr; +}; + struct nrf5_info { unsigned int refcount; @@ -127,6 +129,9 @@ struct nrf5_info { enum nrf5_features features; unsigned int flash_size_kb; unsigned int ram_size_kb; + + const struct nrf5_map *map; + const struct nrf5_ficr_map *ficr_offsets; }; #define NRF51_DEVICE_DEF(id, pt, var, bcode, fsize) \ @@ -238,6 +243,31 @@ static const struct nrf5_device_package nrf52_packages_table[] = { { 0x2009, "CF" }, }; +static const struct nrf5_ficr_map nrf51_52_ficr_offsets = { + .codepagesize = 0x10, + .codesize = 0x14, + + /* CONFIGID is documented on nRF51 series only. + * On nRF52 is present but not documented */ + .configid = 0x5c, + + /* Following registers are available on nRF52 and on nRF51 since rev 3 */ + .info_part = 0x100, + .info_variant = 0x104, + .info_package = 0x108, + .info_ram = 0x10c, + .info_flash = 0x110, +}; + +static const struct nrf5_map nrf51_52_map = { + .flash_base = NRF5_FLASH_BASE, + .ficr_base = NRF51_52_FICR_BASE, + .uicr_base = NRF51_52_UICR_BASE, + .nvmc_base = 0x4001E000, + + .watchdog_refresh_addr = 0x40010600, +}; + const struct flash_driver nrf5_flash, nrf51_flash; static bool nrf5_bank_is_probed(const struct flash_bank *bank) @@ -248,6 +278,24 @@ static bool nrf5_bank_is_probed(const struct flash_bank *bank) return nbank->probed; } +static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank) +{ + struct nrf5_info *chip = nbank->chip; + assert(chip); + + return nbank == &chip->bank[1]; +} + +static int nrf5_nvmc_read_u32(struct nrf5_info *chip, uint32_t reg_offset, uint32_t *value) +{ + return target_read_u32(chip->target, chip->map->nvmc_base + reg_offset, value); +} + +static int nrf5_nvmc_write_u32(struct nrf5_info *chip, uint32_t reg_offset, uint32_t value) +{ + return target_write_u32(chip->target, chip->map->nvmc_base + reg_offset, value); +} + static int nrf5_wait_for_nvmc(struct nrf5_info *chip) { uint32_t ready; @@ -256,7 +304,7 @@ static int nrf5_wait_for_nvmc(struct nrf5_info *chip) int64_t ts_start = timeval_ms(); do { - res = target_read_u32(chip->target, NRF5_NVMC_READY, &ready); + res = nrf5_nvmc_read_u32(chip, NRF5_NVMC_READY, &ready); if (res != ERROR_OK) { LOG_ERROR("Error waiting NVMC_READY: generic flash write/erase error (check protection etc...)"); return res; @@ -276,7 +324,7 @@ static int nrf5_wait_for_nvmc(struct nrf5_info *chip) static int nrf5_nvmc_erase_enable(struct nrf5_info *chip) { int res; - res = target_write_u32(chip->target, + res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_CONFIG, NRF5_NVMC_CONFIG_EEN); @@ -299,7 +347,7 @@ static int nrf5_nvmc_erase_enable(struct nrf5_info *chip) static int nrf5_nvmc_write_enable(struct nrf5_info *chip) { int res; - res = target_write_u32(chip->target, + res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_CONFIG, NRF5_NVMC_CONFIG_WEN); @@ -322,7 +370,7 @@ static int nrf5_nvmc_write_enable(struct nrf5_info *chip) static int nrf5_nvmc_read_only(struct nrf5_info *chip) { int res; - res = target_write_u32(chip->target, + res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_CONFIG, NRF5_NVMC_CONFIG_REN); @@ -350,7 +398,7 @@ static int nrf5_nvmc_generic_erase(struct nrf5_info *chip, if (res != ERROR_OK) goto error; - res = target_write_u32(chip->target, + res = nrf5_nvmc_write_u32(chip, erase_register, erase_value); if (res != ERROR_OK) @@ -370,7 +418,8 @@ error: return ERROR_FAIL; } -static int nrf5_protect_check_clenr0(struct flash_bank *bank) +/* nRF51 series only */ +static int nrf51_protect_check_clenr0(struct flash_bank *bank) { int res; uint32_t clenr0; @@ -403,7 +452,8 @@ static int nrf5_protect_check_clenr0(struct flash_bank *bank) return ERROR_OK; } -static int nrf5_protect_check_bprot(struct flash_bank *bank) +/* nRF52 series only */ +static int nrf52_protect_check_bprot(struct flash_bank *bank) { struct nrf5_bank *nbank = bank->driver_priv; assert(nbank); @@ -432,26 +482,27 @@ static int nrf5_protect_check_bprot(struct flash_bank *bank) static int nrf5_protect_check(struct flash_bank *bank) { - /* UICR cannot be write protected so just return early */ - if (bank->base == NRF5_UICR_BASE) - return ERROR_OK; - struct nrf5_bank *nbank = bank->driver_priv; assert(nbank); struct nrf5_info *chip = nbank->chip; assert(chip); + /* UICR cannot be write protected so just return early */ + if (nrf5_bank_is_uicr(nbank)) + return ERROR_OK; + if (chip->features & NRF5_FEATURE_BPROT) - return nrf5_protect_check_bprot(bank); + return nrf52_protect_check_bprot(bank); if (chip->features & NRF5_FEATURE_SERIES_51) - return nrf5_protect_check_clenr0(bank); + return nrf51_protect_check_clenr0(bank); LOG_WARNING("Flash protection of this nRF device is not supported"); return ERROR_FLASH_OPER_UNSUPPORTED; } -static int nrf5_protect_clenr0(struct flash_bank *bank, int set, unsigned int first, +/* nRF51 series only */ +static int nrf51_protect_clenr0(struct flash_bank *bank, int set, unsigned int first, unsigned int last) { int res; @@ -517,8 +568,13 @@ error: static int nrf5_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last) { + struct nrf5_bank *nbank = bank->driver_priv; + assert(nbank); + struct nrf5_info *chip = nbank->chip; + assert(chip); + /* UICR cannot be write protected so just bail out early */ - if (bank->base == NRF5_UICR_BASE) { + if (nrf5_bank_is_uicr(nbank)) { LOG_ERROR("UICR page does not support protection"); return ERROR_FLASH_OPER_UNSUPPORTED; } @@ -528,13 +584,8 @@ static int nrf5_protect(struct flash_bank *bank, int set, unsigned int first, return ERROR_TARGET_NOT_HALTED; } - struct nrf5_bank *nbank = bank->driver_priv; - assert(nbank); - struct nrf5_info *chip = nbank->chip; - assert(chip); - if (chip->features & NRF5_FEATURE_SERIES_51) - return nrf5_protect_clenr0(bank, set, first, last); + return nrf51_protect_clenr0(bank, set, first, last); LOG_ERROR("Flash protection setting is not supported on this nRF5 device"); return ERROR_FLASH_OPER_UNSUPPORTED; @@ -564,7 +615,7 @@ static const char *nrf5_decode_info_package(uint32_t package) return "xx"; } -static int get_nrf5_chip_type_str(const struct nrf5_info *chip, char *buf, unsigned int buf_size) +static int nrf5_get_chip_type_str(const struct nrf5_info *chip, char *buf, unsigned int buf_size) { int res; if (chip->spec) { @@ -597,7 +648,7 @@ static int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd) assert(chip); char chip_type_str[256]; - if (get_nrf5_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK) + if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK) return ERROR_FAIL; command_print_sameline(cmd, "%s %ukB Flash, %ukB RAM", @@ -605,14 +656,16 @@ static int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd) return ERROR_OK; } -static int nrf5_read_ficr_info(struct nrf5_info *chip) +static int nrf5_read_ficr_info(struct nrf5_info *chip, const struct nrf5_map *map, + const struct nrf5_ficr_map *ficr_offsets) { int res; struct target *target = chip->target; + uint32_t ficr_base = map->ficr_base; chip->ficr_info_valid = false; - res = target_read_u32(target, NRF5_FICR_INFO_PART, &chip->ficr_info.part); + res = target_read_u32(target, ficr_base + ficr_offsets->info_part, &chip->ficr_info.part); if (res != ERROR_OK) { LOG_DEBUG("Couldn't read FICR INFO.PART register"); return res; @@ -655,19 +708,19 @@ static int nrf5_read_ficr_info(struct nrf5_info *chip) * VARIANT and PACKAGE coding is unknown for a nRF51 device. * nRF52 devices have FICR INFO documented and always filled. */ - res = target_read_u32(target, NRF5_FICR_INFO_VARIANT, &chip->ficr_info.variant); + res = target_read_u32(target, ficr_base + ficr_offsets->info_variant, &chip->ficr_info.variant); if (res != ERROR_OK) return res; - res = target_read_u32(target, NRF5_FICR_INFO_PACKAGE, &chip->ficr_info.package); + res = target_read_u32(target, ficr_base + ficr_offsets->info_package, &chip->ficr_info.package); if (res != ERROR_OK) return res; - res = target_read_u32(target, NRF5_FICR_INFO_RAM, &chip->ficr_info.ram); + res = target_read_u32(target, ficr_base + ficr_offsets->info_ram, &chip->ficr_info.ram); if (res != ERROR_OK) return res; - res = target_read_u32(target, NRF5_FICR_INFO_FLASH, &chip->ficr_info.flash); + res = target_read_u32(target, ficr_base + ficr_offsets->info_flash, &chip->ficr_info.flash); if (res != ERROR_OK) return res; @@ -675,7 +728,8 @@ static int nrf5_read_ficr_info(struct nrf5_info *chip) return ERROR_OK; } -static int nrf5_get_ram_size(struct target *target, uint32_t *ram_size) +/* nRF51 series only */ +static int nrf51_get_ram_size(struct target *target, uint32_t *ram_size) { int res; @@ -718,24 +772,33 @@ static int nrf5_probe(struct flash_bank *bank) assert(chip); struct target *target = chip->target; - uint32_t configid; - res = target_read_u32(target, NRF5_FICR_CONFIGID, &configid); + chip->spec = NULL; + + /* guess a nRF51 series if the device has no FICR INFO and we don't know HWID */ + chip->features = NRF5_FEATURE_SERIES_51; + chip->map = &nrf51_52_map; + chip->ficr_offsets = &nrf51_52_ficr_offsets; + + /* Don't bail out on error for the case that some old engineering + * sample has FICR INFO registers unreadable. We can proceed anyway. */ + (void)nrf5_read_ficr_info(chip, chip->map, chip->ficr_offsets); + + const struct nrf5_ficr_map *ficr_offsets = chip->ficr_offsets; + uint32_t ficr_base = chip->map->ficr_base; + uint32_t configid = 0; + res = target_read_u32(target, ficr_base + ficr_offsets->configid, &configid); if (res != ERROR_OK) { - LOG_ERROR("Couldn't read CONFIGID register"); - return res; + if (chip->features & NRF5_FEATURE_SERIES_51) { + LOG_ERROR("Couldn't read FICR CONFIGID register"); + return res; + } + + LOG_DEBUG("Couldn't read FICR CONFIGID register, using FICR INFO"); } /* HWID is stored in the lower two bytes of the CONFIGID register */ chip->hwid = configid & 0xFFFF; - /* guess a nRF51 series if the device has no FICR INFO and we don't know HWID */ - chip->features = NRF5_FEATURE_SERIES_51; - - /* Don't bail out on error for the case that some old engineering - * sample has FICR INFO registers unreadable. We can proceed anyway. */ - (void)nrf5_read_ficr_info(chip); - - chip->spec = NULL; for (size_t i = 0; i < ARRAY_SIZE(nrf5_known_devices_table); i++) { if (chip->hwid == nrf5_known_devices_table[i].hwid) { chip->spec = &nrf5_known_devices_table[i]; @@ -753,15 +816,17 @@ static int nrf5_probe(struct flash_bank *bank) if (chip->ficr_info_valid) { chip->ram_size_kb = chip->ficr_info.ram; - } else { + } else if (chip->features & NRF5_FEATURE_SERIES_51) { uint32_t ram_size; - nrf5_get_ram_size(target, &ram_size); + nrf51_get_ram_size(target, &ram_size); chip->ram_size_kb = ram_size / 1024; + } else { + chip->ram_size_kb = 0; } - /* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */ + /* The value stored in FICR CODEPAGESIZE is the number of bytes in one page of FLASH. */ uint32_t flash_page_size; - res = target_read_u32(chip->target, NRF5_FICR_CODEPAGESIZE, + res = target_read_u32(chip->target, ficr_base + ficr_offsets->codepagesize, &flash_page_size); if (res != ERROR_OK) { LOG_ERROR("Couldn't read code page size"); @@ -769,9 +834,10 @@ static int nrf5_probe(struct flash_bank *bank) } /* Note the register name is misleading, - * NRF5_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */ + * FICR CODESIZE is the number of pages in flash memory, not the number of bytes! */ uint32_t num_sectors; - res = target_read_u32(chip->target, NRF5_FICR_CODESIZE, &num_sectors); + res = target_read_u32(chip->target, ficr_base + ficr_offsets->codesize, + &num_sectors); if (res != ERROR_OK) { LOG_ERROR("Couldn't read code memory size"); return res; @@ -781,7 +847,7 @@ static int nrf5_probe(struct flash_bank *bank) if (!chip->bank[0].probed && !chip->bank[1].probed) { char chip_type_str[256]; - if (get_nrf5_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK) + if (nrf5_get_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", @@ -793,7 +859,7 @@ static int nrf5_probe(struct flash_bank *bank) free(bank->sectors); - if (bank->base == NRF5_FLASH_BASE) { + if (bank->base == chip->map->flash_base) { /* Sanity check */ if (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb) LOG_WARNING("Chip's reported Flash capacity does not match expected one"); @@ -810,6 +876,7 @@ static int nrf5_probe(struct flash_bank *bank) chip->bank[0].probed = true; } else { + /* UICR bank */ bank->num_sectors = 1; bank->size = flash_page_size; @@ -849,7 +916,7 @@ static int nrf5_erase_page(struct flash_bank *bank, LOG_DEBUG("Erasing page at 0x%"PRIx32, sector->offset); - if (bank->base == NRF5_UICR_BASE) { + if (bank->base == chip->map->uicr_base) { if (chip->features & NRF5_FEATURE_SERIES_51) { uint32_t ppfc; res = target_read_u32(chip->target, NRF51_FICR_PPFC, @@ -958,7 +1025,7 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const u buf_set_u32(reg_params[2].value, 0, 32, source->address + source->size); buf_set_u32(reg_params[3].value, 0, 32, address); buf_set_u32(reg_params[4].value, 0, 32, WATCHDOG_REFRESH_VALUE); - buf_set_u32(reg_params[5].value, 0, 32, WATCHDOG_REFRESH_REGISTER); + buf_set_u32(reg_params[5].value, 0, 32, chip->map->watchdog_refresh_addr); retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4, 0, NULL, @@ -1008,7 +1075,7 @@ static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer, * is protected. */ if (chip->features & NRF5_FEATURE_SERIES_51) { - res = nrf5_protect_check_clenr0(bank); + res = nrf51_protect_check_clenr0(bank); if (res != ERROR_OK) return res; @@ -1065,7 +1132,7 @@ static int nrf5_erase(struct flash_bank *bank, unsigned int first, * is protected. */ if (chip->features & NRF5_FEATURE_SERIES_51) { - res = nrf5_protect_check_clenr0(bank); + res = nrf51_protect_check_clenr0(bank); if (res != ERROR_OK) return res; } @@ -1136,7 +1203,7 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) switch (bank->base) { case NRF5_FLASH_BASE: - case NRF5_UICR_BASE: + case NRF51_52_UICR_BASE: break; default: LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base); @@ -1157,7 +1224,7 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) case NRF5_FLASH_BASE: nbank = &chip->bank[0]; break; - case NRF5_UICR_BASE: + case NRF51_52_UICR_BASE: nbank = &chip->bank[1]; break; } From fc7a428fc2a5d1e74621e56a2cbd2c31566fc63f Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 22 Jan 2024 14:17:27 +0100 Subject: [PATCH 16/47] flash/nor/nrf5: make flash erase little faster Enable and disable erase mode only once instead of toggling it for each sector. Refactor to decrease the number of call levels. Change-Id: Ie546a4fc24da0eea2753a2bebaa63d941ef7aa1d Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/8111 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/nrf5.c | 85 ++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 50 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index b4a8e979e..641f3ab21 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -375,7 +375,7 @@ static int nrf5_nvmc_read_only(struct nrf5_info *chip) NRF5_NVMC_CONFIG_REN); if (res != ERROR_OK) { - LOG_ERROR("Failed to enable read-only operation"); + LOG_ERROR("Failed to disable write/erase operation"); return res; } /* @@ -389,35 +389,6 @@ static int nrf5_nvmc_read_only(struct nrf5_info *chip) return res; } -static int nrf5_nvmc_generic_erase(struct nrf5_info *chip, - uint32_t erase_register, uint32_t erase_value) -{ - int res; - - res = nrf5_nvmc_erase_enable(chip); - if (res != ERROR_OK) - goto error; - - res = nrf5_nvmc_write_u32(chip, - erase_register, - erase_value); - if (res != ERROR_OK) - goto set_read_only; - - res = nrf5_wait_for_nvmc(chip); - if (res != ERROR_OK) - goto set_read_only; - - return nrf5_nvmc_read_only(chip); - -set_read_only: - nrf5_nvmc_read_only(chip); -error: - LOG_ERROR("Failed to erase reg: 0x%08"PRIx32" val: 0x%08"PRIx32, - erase_register, erase_value); - return ERROR_FAIL; -} - /* nRF51 series only */ static int nrf51_protect_check_clenr0(struct flash_bank *bank) { @@ -900,13 +871,6 @@ static int nrf5_auto_probe(struct flash_bank *bank) return nrf5_probe(bank); } -static int nrf5_erase_all(struct nrf5_info *chip) -{ - LOG_DEBUG("Erasing all non-volatile memory"); - return nrf5_nvmc_generic_erase(chip, - NRF5_NVMC_ERASEALL, - 0x00000001); -} static int nrf5_erase_page(struct flash_bank *bank, struct nrf5_info *chip, @@ -938,17 +902,18 @@ static int nrf5_erase_page(struct flash_bank *bank, } } - res = nrf5_nvmc_generic_erase(chip, - NRF5_NVMC_ERASEUICR, - 0x00000001); - + res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_ERASEUICR, 0x00000001); } else { - res = nrf5_nvmc_generic_erase(chip, - NRF5_NVMC_ERASEPAGE, - sector->offset); + res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_ERASEPAGE, sector->offset); } + if (res != ERROR_OK) { + /* caller logs the error */ + return res; + } + + res = nrf5_wait_for_nvmc(chip); return res; } @@ -1137,13 +1102,18 @@ static int nrf5_erase(struct flash_bank *bank, unsigned int first, return res; } + res = nrf5_nvmc_erase_enable(chip); + if (res != ERROR_OK) + goto error; + /* For each sector to be erased */ for (unsigned int s = first; s <= last; s++) { if (chip->features & NRF5_FEATURE_SERIES_51 && bank->sectors[s].is_protected == 1) { LOG_ERROR("Flash sector %d is protected", s); - return ERROR_FLASH_PROTECTED; + res = ERROR_FLASH_PROTECTED; + break; } res = nrf5_erase_page(bank, chip, &bank->sectors[s]); @@ -1153,7 +1123,9 @@ static int nrf5_erase(struct flash_bank *bank, unsigned int first, } } - return ERROR_OK; +error: + nrf5_nvmc_read_only(chip); + return res; } static void nrf5_free_driver_priv(struct flash_bank *bank) @@ -1277,14 +1249,27 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command) } } - res = nrf5_erase_all(chip); + res = nrf5_nvmc_erase_enable(chip); + if (res != ERROR_OK) + goto error; + + res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_ERASEALL, 0x00000001); + if (res != ERROR_OK) { + LOG_ERROR("Mass erase failed"); + goto error; + } + + res = nrf5_wait_for_nvmc(chip); + if (res != ERROR_OK) + LOG_ERROR("Mass erase did not complete"); + +error: + nrf5_nvmc_read_only(chip); + if (res == ERROR_OK) { LOG_INFO("Mass erase completed."); if (chip->features & NRF5_FEATURE_SERIES_51) LOG_INFO("A reset or power cycle is required if the flash was protected before."); - - } else { - LOG_ERROR("Failed to erase the chip"); } return res; From d94daf776c5778c94b2ead4db4bc368a20ffa5cf Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 22 Jan 2024 12:45:49 +0100 Subject: [PATCH 17/47] flash/nor/nrf5: add basic nRF53 and nRF91 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Probes all flash and UICR areas. Flash erase and write tested. On nRF53 mass erase works on the application core flash bank only. The Tcl script nrf53_recover can serve as the workaround on the network core. TODO: mass erase of the nRF53 network core flash. Some ideas taken from [1] and [2]. Change-Id: I8e27a780f4d82bcabf029f79b87ac46cf6a531c7 Link: [1] 7404: flash: nor: add support for Nordic nRF9160 | https://review.openocd.org/c/openocd/+/7404 Link: [2] 8062: flash: nor: add support for Nordic nRF9160 | https://review.openocd.org/c/openocd/+/8062 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/8112 Reviewed-by: Tomáš Beneš Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 13 +-- src/flash/nor/nrf5.c | 207 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 181 insertions(+), 39 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index b782e0ba9..8c9f3ff84 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -7316,12 +7316,13 @@ flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME @end deffn @deffn {Flash Driver} {nrf5} -All members of the nRF51 microcontroller families from Nordic Semiconductor -include internal flash and use ARM Cortex-M0 core. nRF52 family powered -by ARM Cortex-M4 or M4F core is supported too. nRF52832 is fully supported -including BPROT flash protection scheme. nRF52833 and nRF52840 devices are -supported with the exception of security extensions (flash access control list -- ACL). +Supports all members of the nRF51, nRF52 and nRF53 microcontroller families from +Nordic Semiconductor. nRF91 family is supported too. One driver handles both +the main flash and the UICR area. + +Flash protection is handled on nRF51 family and nRF52805, nRF52810, nRF52811, +nRF52832 devices. Flash access control list (ACL) protection scheme of the newer +devices is not supported. @example flash bank $_FLASHNAME nrf5 0 0x00000000 0 0 $_TARGETNAME diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 641f3ab21..80243ed59 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -79,6 +79,9 @@ enum nrf5_features { NRF5_FEATURE_SERIES_52 = BIT(1), NRF5_FEATURE_BPROT = BIT(2), NRF5_FEATURE_ACL_PROT = BIT(3), + NRF5_FEATURE_SERIES_53 = BIT(4), + NRF5_FEATURE_SERIES_91 = BIT(5), + NRF5_FEATURE_ERASE_BY_FLASH_WR = BIT(6), }; struct nrf5_device_spec { @@ -268,6 +271,55 @@ static const struct nrf5_map nrf51_52_map = { .watchdog_refresh_addr = 0x40010600, }; + +/* Third generation devices (nRF53, nRF91) */ + +static const struct nrf5_ficr_map nrf53_91_ficr_offsets = { + .codepagesize = 0x220, + .codesize = 0x224, + .configid = 0x200, + .info_part = 0x20c, + .info_variant = 0x210, + .info_package = 0x214, + .info_ram = 0x218, + .info_flash = 0x21c, +}; + +enum { + NRF53APP_91_FICR_BASE = 0x00FF0000, + NRF53APP_91_UICR_BASE = 0x00FF8000, + NRF53NET_FLASH_BASE = 0x01000000, + NRF53NET_FICR_BASE = 0x01FF0000, + NRF53NET_UICR_BASE = 0x01FF8000, +}; + +static const struct nrf5_map nrf53app_91_map = { + .flash_base = NRF5_FLASH_BASE, + .ficr_base = NRF53APP_91_FICR_BASE, + .uicr_base = NRF53APP_91_UICR_BASE, + .nvmc_base = 0x50039000, + + .watchdog_refresh_addr = 0x50018600, +}; + +/* nRF53 duality: + * SoC consists of two Cortex-M33 cores: + * - application core with security extensions + * - network core + * Each core has its own RAM, flash, FICR and UICR + * The flash driver probes and handles flash and UICR of one core + * independently of those dedicated to the other core. + */ +static const struct nrf5_map nrf53net_map = { + .flash_base = NRF53NET_FLASH_BASE, + .ficr_base = NRF53NET_FICR_BASE, + .uicr_base = NRF53NET_UICR_BASE, + .nvmc_base = 0x41080000, + + .watchdog_refresh_addr = 0x41080000, +}; + + const struct flash_driver nrf5_flash, nrf51_flash; static bool nrf5_bank_is_probed(const struct flash_bank *bank) @@ -595,10 +647,15 @@ static int nrf5_get_chip_type_str(const struct nrf5_info *chip, char *buf, unsig } 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)", - chip->ficr_info.part, - nrf5_decode_info_package(chip->ficr_info.package), - variant, &variant[2]); + if (chip->features & (NRF5_FEATURE_SERIES_53 | NRF5_FEATURE_SERIES_91)) { + res = snprintf(buf, buf_size, "nRF%" PRIx32 "-%s", + chip->ficr_info.part, variant); + } else { + 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); } @@ -627,26 +684,27 @@ static int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd) return ERROR_OK; } -static int nrf5_read_ficr_info(struct nrf5_info *chip, const struct nrf5_map *map, +static int nrf5_read_ficr_info_part(struct nrf5_info *chip, const struct nrf5_map *map, const struct nrf5_ficr_map *ficr_offsets) { - int res; struct target *target = chip->target; uint32_t ficr_base = map->ficr_base; - chip->ficr_info_valid = false; - - res = target_read_u32(target, ficr_base + ficr_offsets->info_part, &chip->ficr_info.part); - if (res != ERROR_OK) { + int res = target_read_u32(target, ficr_base + ficr_offsets->info_part, &chip->ficr_info.part); + if (res != ERROR_OK) LOG_DEBUG("Couldn't read FICR INFO.PART register"); - return res; - } + + return res; +} + +static int nrf51_52_partno_check(struct nrf5_info *chip) +{ uint32_t series = chip->ficr_info.part & 0xfffff000; switch (series) { case 0x51000: chip->features = NRF5_FEATURE_SERIES_51; - break; + return ERROR_OK; case 0x52000: chip->features = NRF5_FEATURE_SERIES_52; @@ -665,19 +723,40 @@ static int nrf5_read_ficr_info(struct nrf5_info *chip, const struct nrf5_map *ma chip->features |= NRF5_FEATURE_ACL_PROT; break; } - break; + return ERROR_OK; default: LOG_DEBUG("FICR INFO likely not implemented. Invalid PART value 0x%08" - PRIx32, chip->ficr_info.part); + PRIx32, chip->ficr_info.part); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } +} - /* Now we know the device has FICR INFO filled by something relevant: - * Although it is not documented, the tested nRF51 rev 3 devices - * have FICR INFO.PART, RAM and FLASH of the same format as nRF52. - * VARIANT and PACKAGE coding is unknown for a nRF51 device. - * nRF52 devices have FICR INFO documented and always filled. */ +static int nrf53_91_partno_check(struct nrf5_info *chip) +{ + uint32_t series = chip->ficr_info.part & 0xffffff00; + switch (series) { + case 0x5300: + chip->features = NRF5_FEATURE_SERIES_53 | NRF5_FEATURE_ERASE_BY_FLASH_WR; + return ERROR_OK; + + case 0x9100: + chip->features = NRF5_FEATURE_SERIES_91 | NRF5_FEATURE_ERASE_BY_FLASH_WR; + return ERROR_OK; + + default: + LOG_DEBUG("Invalid FICR INFO PART value 0x%08" + PRIx32, chip->ficr_info.part); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } +} + +static int nrf5_read_ficr_more_info(struct nrf5_info *chip) +{ + int res; + struct target *target = chip->target; + const struct nrf5_ficr_map *ficr_offsets = chip->ficr_offsets; + uint32_t ficr_base = chip->map->ficr_base; res = target_read_u32(target, ficr_base + ficr_offsets->info_variant, &chip->ficr_info.variant); if (res != ERROR_OK) @@ -692,11 +771,7 @@ static int nrf5_read_ficr_info(struct nrf5_info *chip, const struct nrf5_map *ma return res; res = target_read_u32(target, ficr_base + ficr_offsets->info_flash, &chip->ficr_info.flash); - if (res != ERROR_OK) - return res; - - chip->ficr_info_valid = true; - return ERROR_OK; + return res; } /* nRF51 series only */ @@ -735,7 +810,7 @@ static int nrf51_get_ram_size(struct target *target, uint32_t *ram_size) static int nrf5_probe(struct flash_bank *bank) { - int res; + int res = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; struct nrf5_bank *nbank = bank->driver_priv; assert(nbank); @@ -744,15 +819,72 @@ static int nrf5_probe(struct flash_bank *bank) struct target *target = chip->target; chip->spec = NULL; + chip->ficr_info_valid = false; - /* guess a nRF51 series if the device has no FICR INFO and we don't know HWID */ - chip->features = NRF5_FEATURE_SERIES_51; - chip->map = &nrf51_52_map; - chip->ficr_offsets = &nrf51_52_ficr_offsets; + /* First try to detect nRF53/91 */ + switch (bank->base) { + case NRF5_FLASH_BASE: + case NRF53APP_91_UICR_BASE: + res = nrf5_read_ficr_info_part(chip, &nrf53app_91_map, &nrf53_91_ficr_offsets); + if (res != ERROR_OK) + break; - /* Don't bail out on error for the case that some old engineering - * sample has FICR INFO registers unreadable. We can proceed anyway. */ - (void)nrf5_read_ficr_info(chip, chip->map, chip->ficr_offsets); + res = nrf53_91_partno_check(chip); + if (res != ERROR_OK) + break; + + chip->map = &nrf53app_91_map; + chip->ficr_offsets = &nrf53_91_ficr_offsets; + break; + + case NRF53NET_FLASH_BASE: + case NRF53NET_UICR_BASE: + res = nrf5_read_ficr_info_part(chip, &nrf53net_map, &nrf53_91_ficr_offsets); + if (res != ERROR_OK) + break; + + res = nrf53_91_partno_check(chip); + if (res != ERROR_OK) + break; + + chip->map = &nrf53net_map; + chip->ficr_offsets = &nrf53_91_ficr_offsets; + break; + + default: + break; + } + + /* If nRF53/91 is not detected, try nRF51/52 */ + if (res != ERROR_OK) { + /* Guess a nRF51 series if the device has no FICR INFO and we don't know HWID */ + chip->features = NRF5_FEATURE_SERIES_51; + chip->map = &nrf51_52_map; + chip->ficr_offsets = &nrf51_52_ficr_offsets; + + /* Don't bail out on error for the case that some old engineering + * sample has FICR INFO registers unreadable. We can proceed anyway. */ + res = nrf5_read_ficr_info_part(chip, chip->map, chip->ficr_offsets); + if (res == ERROR_OK) + res = nrf51_52_partno_check(chip); + } + + if (res == ERROR_OK) { + /* Now we know the device has FICR INFO filled by something relevant: + * Although it is not documented, the tested nRF51 rev 3 devices + * have FICR INFO.PART, RAM and FLASH of the same format as nRF52. + * VARIANT and PACKAGE coding is unknown for a nRF51 device. + * nRF52 devices have FICR INFO documented and always filled. */ + res = nrf5_read_ficr_more_info(chip); + if (res == ERROR_OK) { + chip->ficr_info_valid = true; + } else if (chip->features & NRF5_FEATURE_SERIES_51) { + LOG_DEBUG("Couldn't read some of FICR INFO registers"); + } else { + LOG_ERROR("Couldn't read some of FICR INFO registers"); + return res; + } + } const struct nrf5_ficr_map *ficr_offsets = chip->ficr_offsets; uint32_t ficr_base = chip->map->ficr_base; @@ -904,6 +1036,9 @@ static int nrf5_erase_page(struct flash_bank *bank, res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_ERASEUICR, 0x00000001); + } else if (chip->features & NRF5_FEATURE_ERASE_BY_FLASH_WR) { + res = target_write_u32(chip->target, bank->base + sector->offset, 0xffffffff); + } else { res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_ERASEPAGE, sector->offset); } @@ -1175,7 +1310,10 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) switch (bank->base) { case NRF5_FLASH_BASE: + case NRF53NET_FLASH_BASE: case NRF51_52_UICR_BASE: + case NRF53APP_91_UICR_BASE: + case NRF53NET_UICR_BASE: break; default: LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base); @@ -1194,9 +1332,12 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) switch (bank->base) { case NRF5_FLASH_BASE: + case NRF53NET_FLASH_BASE: nbank = &chip->bank[0]; break; case NRF51_52_UICR_BASE: + case NRF53APP_91_UICR_BASE: + case NRF53NET_UICR_BASE: nbank = &chip->bank[1]; break; } From 17be341d38bda1115b3eb8878ef7f830982fabfb Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 22 Jan 2024 15:33:47 +0100 Subject: [PATCH 18/47] tcl/target: add nRF53 and nRF91 config files Both devices can be configured with or without SWD multidrop. nRF53 network core is examined on demand to avoid problems when the core is forced off. Change-Id: I08f88ff48ff7ac592e9214b89ca8e5e9428573a5 Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/8113 Reviewed-by: Antonio Borneo Tested-by: jenkins --- tcl/target/nrf53.cfg | 146 ++++++++++++++++++++++++++++++++++++++ tcl/target/nrf91.cfg | 63 ++++++++++++++++ tcl/target/nrf_common.cfg | 86 ++++++++++++++++++++++ 3 files changed, 295 insertions(+) create mode 100644 tcl/target/nrf53.cfg create mode 100644 tcl/target/nrf91.cfg create mode 100644 tcl/target/nrf_common.cfg diff --git a/tcl/target/nrf53.cfg b/tcl/target/nrf53.cfg new file mode 100644 index 000000000..307df902c --- /dev/null +++ b/tcl/target/nrf53.cfg @@ -0,0 +1,146 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Nordic nRF53 series: dual ARM Cortex-M33, multidrop SWD +# + +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME nrf53 +} + +# Work-area is a space in RAM used for flash programming +# By default use 16kB +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x4000 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x6ba02477 +} + +# Configurable instance ID resides in application UICR TINSTANCE +if { [info exists SWD_INSTANCE_ID] } { + set _SWD_INSTANCE_ID $SWD_INSTANCE_ID +} else { + set _SWD_INSTANCE_ID 0 +} + +swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID + +if { [info exists SWD_MULTIDROP] } { + dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu -dp-id 0x0070289 -instance-id $_SWD_INSTANCE_ID +} else { + dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu +} + +set _TARGETNAME_APP $_CHIPNAME.cpuapp +target create $_TARGETNAME_APP cortex_m -dap $_CHIPNAME.dap + +$_TARGETNAME_APP configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +# The network core is not accessible over HLA +if { ![using_hla] } { + set _TARGETNAME_NET $_CHIPNAME.cpunet + target create $_TARGETNAME_NET cortex_m -dap $_CHIPNAME.dap -ap-num 1 -defer-examine + + targets $_TARGETNAME_APP + + $_TARGETNAME_NET configure -work-area-phys 0x21000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 +} + +# Keep adapter speed less or equal 2000 kHz or flash programming fails! +adapter speed 1000 + +source [find target/nrf_common.cfg] + +flash bank $_CHIPNAME.app.flash nrf5 0x00000000 0 0 0 $_TARGETNAME_APP +flash bank $_CHIPNAME.app.uicr nrf5 0x00FF8000 0 0 0 $_TARGETNAME_APP + +if { ![using_hla] } { + + flash bank $_CHIPNAME.net.flash nrf5 0x01000000 0 0 0 $_TARGETNAME_NET + flash bank $_CHIPNAME.net.uicr nrf5 0x01FF8000 0 0 0 $_TARGETNAME_NET + + # System reset sets NETWORK.FORCEOFF which keeps the network core in reset + # Don't touch network core during reset + $_TARGETNAME_NET configure -event reset-assert {} + # and start it after application core reset is finished to make all flash accessible + $_TARGETNAME_APP configure -event reset-init "nrf53_cpunet_release $_CHIPNAME" + + $_TARGETNAME_APP cortex_m reset_config sysresetreq + $_TARGETNAME_NET cortex_m reset_config sysresetreq + + $_TARGETNAME_APP configure -event examine-fail { _nrf_check_ap_lock 2 3 } + $_TARGETNAME_NET configure -event examine-fail { _nrf_check_ap_lock 3 3 } + + $_TARGETNAME_NET configure -event gdb-attach "_nrf53_cpunet_gdb_attach $_CHIPNAME" + + proc _nrf53_cpunet_gdb_attach { _CHIPNAME } { + set _TARGETNAME_APP $_CHIPNAME.cpuapp + set _TARGETNAME_NET $_CHIPNAME.cpunet + set RESET_NETWORK_FORCEOFF 0x50005614 + + set is_off [$_TARGETNAME_APP read_memory $RESET_NETWORK_FORCEOFF 32 1] + if { $is_off } { + nrf53_cpunet_release $_CHIPNAME + $_TARGETNAME_NET arp_poll + $_TARGETNAME_NET arp_waitstate halted 100 + } else { + if { ![$_TARGETNAME_NET was_examined] } { + $_TARGETNAME_NET arp_examine + $_TARGETNAME_NET arp_poll + } + set s [$_TARGETNAME_NET curstate] + if { ![string compare $s "halted"] } { + halt + } + } + } + lappend _telnet_autocomplete_skip _nrf53_cpunet_gdb_attach + + # Release the network core + proc nrf53_cpunet_release { {_CHIPNAME nrf53} } { + set _TARGETNAME_APP $_CHIPNAME.cpuapp + set _TARGETNAME_NET $_CHIPNAME.cpunet + set RESET_NETWORK_FORCEOFF 0x50005614 + set RESET_NETWORK_WORKAROUND 0x50005618 + set CORTEX_M_DCB_DEMCR 0xE000EDFC + + $_TARGETNAME_APP mww $RESET_NETWORK_WORKAROUND 1 + $_TARGETNAME_APP mww $RESET_NETWORK_FORCEOFF 0 + $_TARGETNAME_APP mww $RESET_NETWORK_FORCEOFF 1 + set err [catch {$_TARGETNAME_NET arp_examine}] + if { $err } { + if { ![_nrf_check_ap_lock 3 3] } { + echo "Error: \[$_TARGETNAME_NET\] examination failed" + } + return + } + # set TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET + $_TARGETNAME_NET mww $CORTEX_M_DCB_DEMCR 0x01000501 + # Write DEMCR directly intead of permanetly setting by cortex_m vector_catch reset + # following cortex_m_endreset_event() restores the original DEMCR value + $_TARGETNAME_APP mww $RESET_NETWORK_FORCEOFF 0 + $_TARGETNAME_APP mww $RESET_NETWORK_WORKAROUND 0 + } + + # Mass erase and unlock the device using proprietary nRF CTRL-AP (AP #2 or #3) + proc nrf53_cpuapp_recover {} { + _nrf_ctrl_ap_recover 2 + } + add_help_text nrf53_cpuapp_recover "Mass erase flash and unlock nRF53 application CPU" + + proc nrf53_recover {} { + _nrf_ctrl_ap_recover 3 1 + } + add_help_text nrf53_recover "Mass erase all device flash and unlock nRF53" +} diff --git a/tcl/target/nrf91.cfg b/tcl/target/nrf91.cfg new file mode 100644 index 000000000..e0ff4e546 --- /dev/null +++ b/tcl/target/nrf91.cfg @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Nordic nRF91 series: ARM Cortex-M33, SWD only +# + +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME nrf91 +} + +# Work-area is a space in RAM used for flash programming +# By default use 16kB +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x4000 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x6ba02477 +} + +swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID + +# Contrary to the product specification at least nRF9161 supports multidrop SWD. +# The instance ID is fixed, no more than one nRF91 can be connected to one SWD bus. +if { [info exists SWD_MULTIDROP] } { + dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu -dp-id 0x0090289 -instance-id 0 +} else { + dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu +} + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap + +# Keep adapter speed less or equal 2000 kHz or flash programming fails! +adapter speed 1000 + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +source [find target/nrf_common.cfg] + +flash bank $_CHIPNAME.flash nrf5 0x00000000 0 0 0 $_TARGETNAME +flash bank $_CHIPNAME.uicr nrf5 0x00FF8000 0 0 0 $_TARGETNAME + +if { ![using_hla] } { + $_TARGETNAME cortex_m reset_config sysresetreq + + $_TARGETNAME configure -event examine-fail { _nrf_check_ap_lock 4 3 } +} + +# Mass erase and unlock the device using proprietary nRF CTRL-AP (AP #4) +proc nrf91_recover {} { + _nrf_ctrl_ap_recover 4 +} +add_help_text nrf91_recover "Mass erase and unlock nRF91 device" diff --git a/tcl/target/nrf_common.cfg b/tcl/target/nrf_common.cfg new file mode 100644 index 000000000..2ae5011e4 --- /dev/null +++ b/tcl/target/nrf_common.cfg @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Nordic nRF52, nRF53 and nRF91 CTRL-AP handling +# + +if { [using_hla] } { + echo "" + echo "nRF device has a CTRL-AP dedicated to recover the device from AP lock." + echo "A high level adapter (like a ST-Link) you are currently using cannot access" + echo "the CTRL-AP so 'nrfxx_recover' command will not work." + echo "Do not enable UICR APPROTECT." + echo "" +} else { + + # Test if debug/MEM-AP is locked by UICR APPROTECT + proc _nrf_check_ap_lock { ctrl_ap_num unlocked_value } { + set target [target current] + set dap [$target cget -dap] + set err [catch {set APPROTECTSTATUS [$dap apreg $ctrl_ap_num 0xc]}] + if {$err == 0 && $APPROTECTSTATUS < $unlocked_value} { + echo "" + echo "****** WARNING ******" + echo "\[$target\] device has AP lock engaged (see UICR APPROTECT register)." + echo "Debug access is denied." + echo "Use 'nrfxx_recover' to erase and unlock the device." + echo "" + poll off + return 1 + } + return 0 + } + + # Mass erase and unlock the device using proprietary nRF CTRL-AP + proc _nrf_ctrl_ap_recover { ctrl_ap_num {is_cpunet 0} } { + set target [target current] + set dap [$target cget -dap] + + set IDR [$dap apreg $ctrl_ap_num 0xfc] + if {$IDR != 0x12880000} { + echo "Error: Cannot access nRF CTRL-AP!" + return + } + + poll off + + # Reset and trigger ERASEALL task + $dap apreg $ctrl_ap_num 4 0 + $dap apreg $ctrl_ap_num 4 1 + + for {set i 0} {1} {incr i} { + set ERASEALLSTATUS [$dap apreg $ctrl_ap_num 8] + if {$ERASEALLSTATUS == 0} { + echo "\[$target\] device has been successfully erased and unlocked." + break + } + if {$i == 0} { + echo "Waiting for chip erase..." + } + if {$i >= 150} { + echo "Error: \[$target\] recovery failed." + break + } + sleep 100 + } + + # Assert reset + $dap apreg $ctrl_ap_num 0 1 + + # Deassert reset + $dap apreg $ctrl_ap_num 0 0 + + # Reset ERASEALL task + $dap apreg $ctrl_ap_num 4 0 + + if { $is_cpunet } { + reset init + } else { + sleep 100 + $target arp_examine + poll on + } + } + + lappend _telnet_autocomplete_skip _nrf_check_ap_lock _nrf_ctrl_ap_recover +} From 70b362d4f47194eced99b448cc99b093641d1465 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 22 Jan 2024 18:17:48 +0100 Subject: [PATCH 19/47] flash/nor/nrf5: show proper SoC type on newer nRF91 devices Since nRF9160 Product Specification v2.1 the new UICR SIPINFO fields should be preferred over UICR INFO. Tested on nRF9161. Signed-off-by: Tomas Vanek Change-Id: Ib8005b3b6292aa20fa83c1dcebd2de27df58b661 Reviewed-on: https://review.openocd.org/c/openocd/+/8114 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/nrf5.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 80243ed59..cac233d47 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -285,6 +285,22 @@ static const struct nrf5_ficr_map nrf53_91_ficr_offsets = { .info_flash = 0x21c, }; +/* Since nRF9160 Product Specification v2.1 there is + * a new UICR field SIPINFO, which should be preferred. + * The original INFO fields describe just a part of the chip + * (PARTNO=9120 at nRF9161) + */ +static const struct nrf5_ficr_map nrf91new_ficr_offsets = { + .codepagesize = 0x220, + .codesize = 0x224, + .configid = 0x200, + .info_part = 0x140, /* SIPINFO.PARTNO */ + .info_variant = 0x148, /* SIPINFO.VARIANT */ + .info_package = 0x214, + .info_ram = 0x218, + .info_flash = 0x21c, +}; + enum { NRF53APP_91_FICR_BASE = 0x00FF0000, NRF53APP_91_UICR_BASE = 0x00FF8000, @@ -614,12 +630,17 @@ static int nrf5_protect(struct flash_bank *bank, int set, unsigned int first, return ERROR_FLASH_OPER_UNSUPPORTED; } -static bool nrf5_info_variant_to_str(uint32_t variant, char *bf) +static bool nrf5_info_variant_to_str(uint32_t variant, char *bf, bool swap) { uint8_t b[4]; - h_u32_to_be(b, variant); - if (isalnum(b[0]) && isalnum(b[1]) && isalnum(b[2]) && isalnum(b[3])) { + if (swap) + h_u32_to_le(b, variant); + else + h_u32_to_be(b, variant); + + if (isalnum(b[0]) && isalnum(b[1]) && isalnum(b[2]) && + (isalnum(b[3]) || b[3] == 0)) { memcpy(bf, b, 4); bf[4] = 0; return true; @@ -646,7 +667,10 @@ static int nrf5_get_chip_type_str(const struct nrf5_info *chip, char *buf, unsig 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); + + nrf5_info_variant_to_str(chip->ficr_info.variant, variant, + chip->features & NRF5_FEATURE_SERIES_91); + if (chip->features & (NRF5_FEATURE_SERIES_53 | NRF5_FEATURE_SERIES_91)) { res = snprintf(buf, buf_size, "nRF%" PRIx32 "-%s", chip->ficr_info.part, variant); @@ -825,6 +849,16 @@ static int nrf5_probe(struct flash_bank *bank) switch (bank->base) { case NRF5_FLASH_BASE: case NRF53APP_91_UICR_BASE: + res = nrf5_read_ficr_info_part(chip, &nrf53app_91_map, &nrf91new_ficr_offsets); + if (res == ERROR_OK) { + res = nrf53_91_partno_check(chip); + if (res == ERROR_OK) { + chip->map = &nrf53app_91_map; + chip->ficr_offsets = &nrf91new_ficr_offsets; + break; + } + } + res = nrf5_read_ficr_info_part(chip, &nrf53app_91_map, &nrf53_91_ficr_offsets); if (res != ERROR_OK) break; From e4c0904731320c686e5074e68db8358e2f3ce83d Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 22 Jan 2024 21:09:31 +0100 Subject: [PATCH 20/47] flash/nor/nrf5: handle ERROR_WAIT during nRF91 flash erase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Erase is initiated by write to a flash address. Due to the silicon errata of nRF91 the write stalls the bus until the page erase is finished (takes up to 87ms). If the adapter does not handle SWD WAIT properly, the following read in nrf5_wait_for_nvmc() returns ERROR_WAIT. Wait for fixed time before accessing AP. Not nice, but the only working solution until all adapters handle SWD WAIT. If the fixed wait does not suffice, continue the wait loop after a delay. It makes some unnecessary noise however erase works. Signed-off-by: Tomas Vanek Change-Id: I63faf38dad79440a0117ed79930442bd2843c6db Reviewed-on: https://review.openocd.org/c/openocd/+/8115 Reviewed-by: Tomáš Beneš Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/nrf5.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index cac233d47..f07433e67 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -373,6 +373,12 @@ static int nrf5_wait_for_nvmc(struct nrf5_info *chip) do { res = nrf5_nvmc_read_u32(chip, NRF5_NVMC_READY, &ready); + if (res == ERROR_WAIT) { + /* The adapter does not handle SWD WAIT properly, + * add some delay to reduce number of error messages */ + alive_sleep(10); + continue; + } if (res != ERROR_OK) { LOG_ERROR("Error waiting NVMC_READY: generic flash write/erase error (check protection etc...)"); return res; @@ -1072,6 +1078,22 @@ static int nrf5_erase_page(struct flash_bank *bank, } else if (chip->features & NRF5_FEATURE_ERASE_BY_FLASH_WR) { res = target_write_u32(chip->target, bank->base + sector->offset, 0xffffffff); + /* nRF9160 errata [2] NVMC: CPU code execution from RAM halted during + * flash page erase operation + * https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF9160_Rev1%2FERR%2FnRF9160%2FRev1%2Flatest%2Fanomaly_160_2.html + * affects also erasing by debugger MEM-AP write: + * + * Write to a flash address stalls the bus for 87 ms until + * page erase finishes! This makes problems if the adapter does not + * handle SWD WAIT properly or does not wait long enough. + * Using a target algo would not help, AP gets unresponsive too. + * Neither sending AP ABORT helps, the next AP access stalls again. + * Simply wait long enough before accessing AP again... + * + * The same errata was observed in nRF9161 + */ + if (chip->features & NRF5_FEATURE_SERIES_91) + alive_sleep(90); } else { res = nrf5_nvmc_write_u32(chip, NRF5_NVMC_ERASEPAGE, sector->offset); From 400cf213c05d17cede4dca4787a5533959bd2183 Mon Sep 17 00:00:00 2001 From: Evgeniy Naydanov Date: Mon, 27 May 2024 14:54:05 +0300 Subject: [PATCH 21/47] fix GCC's `-Wcalloc-transposed-args` warning GCC 14.1.0 warns about calls to `calloc()` with element size as the first argument. Link: https://gcc.gnu.org/onlinedocs/gcc-14.1.0/gcc/Warning-Options.html#index-Wcalloc-transposed-args Change-Id: I7d44a74a003ee6ec49d165f91727972478214587 Signed-off-by: Evgeniy Naydanov Reviewed-on: https://review.openocd.org/c/openocd/+/8301 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- src/flash/nor/ambiqmicro.c | 2 +- src/flash/nor/at91sam7.c | 4 ++-- src/flash/nor/kinetis.c | 4 ++-- src/flash/nor/max32xxx.c | 2 +- src/flash/nor/msp432.c | 2 +- src/flash/nor/stellaris.c | 2 +- src/flash/nor/stm32f2x.c | 2 +- src/jtag/drivers/angie.c | 2 +- src/jtag/drivers/ulink.c | 2 +- src/target/arc_jtag.c | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/flash/nor/ambiqmicro.c b/src/flash/nor/ambiqmicro.c index 2b458bc8f..bb893778c 100644 --- a/src/flash/nor/ambiqmicro.c +++ b/src/flash/nor/ambiqmicro.c @@ -124,7 +124,7 @@ FLASH_BANK_COMMAND_HANDLER(ambiqmicro_flash_bank_command) if (CMD_ARGC < 6) return ERROR_COMMAND_SYNTAX_ERROR; - ambiqmicro_info = calloc(sizeof(struct ambiqmicro_flash_bank), 1); + ambiqmicro_info = calloc(1, sizeof(struct ambiqmicro_flash_bank)); bank->driver_priv = ambiqmicro_info; diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c index 6879a1bf2..86c80765f 100644 --- a/src/flash/nor/at91sam7.c +++ b/src/flash/nor/at91sam7.c @@ -560,7 +560,7 @@ static int at91sam7_read_part_info(struct flash_bank *bank) if (bnk > 0) { if (!t_bank->next) { /* create a new flash bank element */ - struct flash_bank *fb = calloc(sizeof(struct flash_bank), 1); + struct flash_bank *fb = calloc(1, sizeof(struct flash_bank)); if (!fb) { LOG_ERROR("No memory for flash bank"); return ERROR_FAIL; @@ -748,7 +748,7 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) if (bnk > 0) { if (!t_bank->next) { /* create a new bank element */ - struct flash_bank *fb = calloc(sizeof(struct flash_bank), 1); + struct flash_bank *fb = calloc(1, sizeof(struct flash_bank)); if (!fb) { LOG_ERROR("No memory for flash bank"); return ERROR_FAIL; diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index e8074e35b..fee36444e 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -930,7 +930,7 @@ FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command) k_chip = kinetis_get_chip(target); if (!k_chip) { - k_chip = calloc(sizeof(struct kinetis_chip), 1); + k_chip = calloc(1, sizeof(struct kinetis_chip)); if (!k_chip) { LOG_ERROR("No memory"); return ERROR_FAIL; @@ -1031,7 +1031,7 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip) bank_idx - k_chip->num_pflash_blocks); } - bank = calloc(sizeof(struct flash_bank), 1); + bank = calloc(1, sizeof(struct flash_bank)); if (!bank) return ERROR_FAIL; diff --git a/src/flash/nor/max32xxx.c b/src/flash/nor/max32xxx.c index 51d6ae271..59a14af8b 100644 --- a/src/flash/nor/max32xxx.c +++ b/src/flash/nor/max32xxx.c @@ -87,7 +87,7 @@ FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command) return ERROR_FLASH_BANK_INVALID; } - info = calloc(sizeof(struct max32xxx_flash_bank), 1); + info = calloc(1, sizeof(struct max32xxx_flash_bank)); COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], info->flash_size); COMMAND_PARSE_NUMBER(uint, CMD_ARGV[6], info->flc_base); COMMAND_PARSE_NUMBER(uint, CMD_ARGV[7], info->sector_size); diff --git a/src/flash/nor/msp432.c b/src/flash/nor/msp432.c index 5e2935d02..b5e2b0bf8 100644 --- a/src/flash/nor/msp432.c +++ b/src/flash/nor/msp432.c @@ -937,7 +937,7 @@ static int msp432_probe(struct flash_bank *bank) if (is_main && MSP432P4 == msp432_bank->family_type) { /* Create the info flash bank needed by MSP432P4 variants */ - struct flash_bank *info = calloc(sizeof(struct flash_bank), 1); + struct flash_bank *info = calloc(1, sizeof(struct flash_bank)); if (!info) return ERROR_FAIL; diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index 972686e3f..eab6244d4 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -453,7 +453,7 @@ FLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command) if (CMD_ARGC < 6) return ERROR_COMMAND_SYNTAX_ERROR; - stellaris_info = calloc(sizeof(struct stellaris_flash_bank), 1); + stellaris_info = calloc(1, sizeof(struct stellaris_flash_bank)); bank->base = 0x0; bank->driver_priv = stellaris_info; diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c index 4e0f73182..3bafde56f 100644 --- a/src/flash/nor/stm32f2x.c +++ b/src/flash/nor/stm32f2x.c @@ -1020,7 +1020,7 @@ static int stm32x_probe(struct flash_bank *bank) assert(num_sectors > 0); bank->num_sectors = num_sectors; - bank->sectors = calloc(sizeof(struct flash_sector), num_sectors); + bank->sectors = calloc(num_sectors, sizeof(struct flash_sector)); if (stm32x_otp_is_f7(bank)) bank->size = STM32F7_OTP_SIZE; diff --git a/src/jtag/drivers/angie.c b/src/jtag/drivers/angie.c index c024667bd..81dd1af82 100644 --- a/src/jtag/drivers/angie.c +++ b/src/jtag/drivers/angie.c @@ -1597,7 +1597,7 @@ static int angie_queue_scan(struct angie *device, struct jtag_command *cmd) /* Allocate TDO buffer if required */ if (type == SCAN_IN || type == SCAN_IO) { - tdo_buffer_start = calloc(sizeof(uint8_t), scan_size_bytes); + tdo_buffer_start = calloc(scan_size_bytes, sizeof(uint8_t)); if (!tdo_buffer_start) return ERROR_FAIL; diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index 4f23c6c7f..0fe8989b9 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -1473,7 +1473,7 @@ static int ulink_queue_scan(struct ulink *device, struct jtag_command *cmd) /* Allocate TDO buffer if required */ if ((type == SCAN_IN) || (type == SCAN_IO)) { - tdo_buffer_start = calloc(sizeof(uint8_t), scan_size_bytes); + tdo_buffer_start = calloc(scan_size_bytes, sizeof(uint8_t)); if (!tdo_buffer_start) return ERROR_FAIL; diff --git a/src/target/arc_jtag.c b/src/target/arc_jtag.c index ddb4f6232..a186709c6 100644 --- a/src/target/arc_jtag.c +++ b/src/target/arc_jtag.c @@ -298,7 +298,7 @@ static int arc_jtag_read_registers(struct arc_jtag *jtag_info, uint32_t type, ARC_JTAG_READ_FROM_CORE_REG : ARC_JTAG_READ_FROM_AUX_REG); arc_jtag_enque_set_transaction(jtag_info, transaction, TAP_DRPAUSE); - uint8_t *data_buf = calloc(sizeof(uint8_t), count * 4); + uint8_t *data_buf = calloc(count * 4, sizeof(uint8_t)); arc_jtag_enque_register_rw(jtag_info, addr, data_buf, NULL, count); @@ -498,7 +498,7 @@ int arc_jtag_read_memory(struct arc_jtag *jtag_info, uint32_t addr, if (!count) return ERROR_OK; - data_buf = calloc(sizeof(uint8_t), count * 4); + data_buf = calloc(count * 4, sizeof(uint8_t)); arc_jtag_enque_reset_transaction(jtag_info); /* We are reading from memory. */ From b49e03f77ed890b39274d94ae6267bf07a68ba98 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 26 May 2024 12:38:43 +0200 Subject: [PATCH 22/47] target/arm_tpiu_swo: Fix memory leak on error In case of fail to allocate 'obj->name', the memory allocated for 'obj->out_filename' is not freed, thus leaking. Since 'obj' is allocated with calloc(), thus zeroed, switch to use the common error exit path for both allocations of 'obj->name' and 'obj->out_filename'. Fixes: 2506ccb50915 ("target/arm_tpiu_swo: Fix division by zero") Change-Id: I412f66ddd7bf7d260cee495324058482b26ff0c5 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8300 Tested-by: jenkins Reviewed-by: zapb --- src/target/arm_tpiu_swo.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index b5a488201..55a977844 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -965,8 +965,7 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const obj->out_filename = strdup("external"); if (!obj->out_filename) { LOG_ERROR("Out of memory"); - free(obj); - return JIM_ERR; + goto err_exit; } Jim_Obj *n; @@ -974,8 +973,7 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const obj->name = strdup(Jim_GetString(n, NULL)); if (!obj->name) { LOG_ERROR("Out of memory"); - free(obj); - return JIM_ERR; + goto err_exit; } /* Do the rest as "configure" options */ From ed30c9a572ba8b7e8959f8998ebfeaaa12a37d70 Mon Sep 17 00:00:00 2001 From: George Voicu Date: Sat, 5 Nov 2022 10:48:47 +0100 Subject: [PATCH 23/47] tcl/fpga/xilinx-dna: Support for reading Spartan3 DNA code Add Xilinx Spartan3 ISC_DNA instruction Signed-off-by: George Voicu Change-Id: Iaddb079c9fdd1b91c65def36878fe81783098696 Reviewed-on: https://review.openocd.org/c/openocd/+/7331 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/fpga/xilinx-dna.cfg | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tcl/fpga/xilinx-dna.cfg b/tcl/fpga/xilinx-dna.cfg index 56f8c1411..6b16b78fb 100644 --- a/tcl/fpga/xilinx-dna.cfg +++ b/tcl/fpga/xilinx-dna.cfg @@ -1,7 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-or-later +# Spartan3: Table 9-5 in https://www.xilinx.com/support/documentation/user_guides/ug332.pdf proc xilinx_dna_addr {chip} { array set addrs { + Spartan3 0x31 Spartan6 0x30 Series7 0x17 } @@ -43,3 +45,7 @@ proc xc7_get_dna {tap} { proc xc6s_get_dna {tap} { return [xilinx_get_dna $tap Spartan6] } + +proc xc3s_get_dna {tap} { + return [xilinx_get_dna $tap Spartan3] +} From a420f00d106cb2638bb4c272a4780e05623ea64b Mon Sep 17 00:00:00 2001 From: George Voicu Date: Sat, 5 Nov 2022 11:08:43 +0100 Subject: [PATCH 24/47] tcl/fpga: Support for Xilinx Spartan3 series devices Tap definition for Xilinx Spartan 3/3E/3A/3AN/3A-DSP devices. Signed-off-by: George Voicu Change-Id: Ieda2b61fc270840f9192976697fcac259c45e3b8 Reviewed-on: https://review.openocd.org/c/openocd/+/7335 Reviewed-by: Antonio Borneo Tested-by: jenkins --- tcl/fpga/xilinx-xc3s.cfg | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tcl/fpga/xilinx-xc3s.cfg diff --git a/tcl/fpga/xilinx-xc3s.cfg b/tcl/fpga/xilinx-xc3s.cfg new file mode 100644 index 000000000..7c17206c9 --- /dev/null +++ b/tcl/fpga/xilinx-xc3s.cfg @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Xilinx Spartan3 generation +# https://www.xilinx.com/support/documentation/user_guides/ug331.pdf + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME xc3s +} + +# Table 12-4 in https://www.xilinx.com/support/documentation/user_guides/ug332.pdf +# the 4 top bits (28:31) are the die stepping, ignore them. +jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \ + -expected-id 0x02210093 \ + -expected-id 0x02218093 \ + -expected-id 0x02220093 \ + -expected-id 0x02228093 \ + -expected-id 0x02230093 \ + -expected-id 0x02610093 \ + -expected-id 0x02618093 \ + -expected-id 0x02620093 \ + -expected-id 0x02628093 \ + -expected-id 0x02630093 \ + -expected-id 0x03840093 \ + -expected-id 0x0384E093 \ + -expected-id 0x01C10093 \ + -expected-id 0x01C1A093 \ + -expected-id 0x01C22093 \ + -expected-id 0x01C2E093 \ + -expected-id 0x01C3A093 \ + -expected-id 0x0140C093 \ + -expected-id 0x01414093 \ + -expected-id 0x0141C093 \ + -expected-id 0x01428093 \ + -expected-id 0x01434093 \ + -expected-id 0x01440093 \ + -expected-id 0x01448093 \ + -expected-id 0x01450093 + +pld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap + +source [find fpga/xilinx-dna.cfg] From b1600bb342e191463094f534f71a4e5d51407e18 Mon Sep 17 00:00:00 2001 From: George Voicu Date: Sat, 5 Nov 2022 11:14:22 +0100 Subject: [PATCH 25/47] tcl/board: Support for Digilent Nexys 2 board Support Digilent Nexys 2 board JTAG chain Signed-off-by: George Voicu Change-Id: I350f80b49303c4b0402d93ebc120a591ef727551 Reviewed-on: https://review.openocd.org/c/openocd/+/7336 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/board/digilent_nexys2.cfg | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tcl/board/digilent_nexys2.cfg diff --git a/tcl/board/digilent_nexys2.cfg b/tcl/board/digilent_nexys2.cfg new file mode 100644 index 000000000..c1c5b2ac6 --- /dev/null +++ b/tcl/board/digilent_nexys2.cfg @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# https://digilent.com/reference/programmable-logic/nexys-2/start +# +# The Digilent Nexy2 normally requires proprietary tools to program and will +# enumerate as: +# ID 1443:0005 1443 ONBOARD USB +# +# However, the ixo-usb-jtag project provides an alternative open firmware for +# the on board programmer. When using this firmware the board will then +# enumerate as: +# ID 16c0:06ad ixo.de USB-JTAG-IF (With SerialNumber == hw_nexys) +# +# See the interface/usb-jtag.cfg for more information. + +source [find interface/usb-jtag.cfg] +source [find cpld/xilinx-xcf-s.cfg] +source [find fpga/xilinx-xc3s.cfg] + +# Usage: +# +# Load Bitstream into FPGA: +# openocd -f board/digilent_nexys2.cfg -c "init;\ +# pld load 0 bitstream.bit;\ +# shutdown" + +# Read Unique Device Identifier (DNA): +# openocd -f board/digilent_nexys2.cfg -c "init;\ +# xilinx_print_dna [xc3s_get_dna xc3s.tap];\ +# shutdown" From 7e4c9609ca9dfd2734f59d6261d2681b2211283b Mon Sep 17 00:00:00 2001 From: Daniel Anselmi Date: Fri, 23 Feb 2024 20:49:54 +0100 Subject: [PATCH 26/47] pld/intel: remove duplicated code Change-Id: I043d16c77ce97d3e888774747ed6bfc4c7e63c04 Signed-off-by: Daniel Anselmi Reviewed-on: https://review.openocd.org/c/openocd/+/8082 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/pld/intel.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pld/intel.c b/src/pld/intel.c index a39e16c21..fe85cd62c 100644 --- a/src/pld/intel.c +++ b/src/pld/intel.c @@ -248,9 +248,6 @@ static int intel_load(struct pld_device *pld_device, const char *filename) if (retval != ERROR_OK) return retval; - if (retval != ERROR_OK) - return retval; - retval = intel_set_instr(tap, 0x002); if (retval != ERROR_OK) { free(bit_file.data); From 9bc7a381b26703f38752771b924fe1c4b918b23d Mon Sep 17 00:00:00 2001 From: Daniel Anselmi Date: Mon, 19 Feb 2024 23:22:19 +0100 Subject: [PATCH 27/47] pld/intel: remove idcodes from intel.c Remove list of id codes for all families. Maintain a list with id, bscan-length and check position in the tcl config files for each family. The Intel FPGA Driver option 'family' is not otional anymore. Change-Id: I9a40a041069e84f6b4728f2cd715756a36759c89 Signed-off-by: Daniel Anselmi Reviewed-on: https://review.openocd.org/c/openocd/+/8083 Reviewed-by: Antonio Borneo Tested-by: jenkins --- doc/openocd.texi | 5 +- src/jtag/tcl.c | 5 +- src/pld/intel.c | 172 ++++---------------------------- tcl/fpga/altera-arriaii.cfg | 27 +++-- tcl/fpga/altera-cyclone10.cfg | 44 ++++---- tcl/fpga/altera-cycloneiii.cfg | 43 ++++---- tcl/fpga/altera-cycloneiv.cfg | 53 +++++----- tcl/fpga/altera-cyclonev.cfg | 58 +++++------ tcl/fpga/altera_common_init.cfg | 9 ++ 9 files changed, 152 insertions(+), 264 deletions(-) create mode 100644 tcl/fpga/altera_common_init.cfg diff --git a/doc/openocd.texi b/doc/openocd.texi index 8c9f3ff84..03fa94466 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -8886,13 +8886,12 @@ For the option @option{-family} @var{name} is one of @var{trion|titanium}. @end deffn -@deffn {FPGA Driver} {intel} [@option{-family} ] +@deffn {FPGA Driver} {intel} @option{-family} This driver can be used to load the bitstream into Intel (former Altera) FPGAs. The families Cyclone III, Cyclone IV, Cyclone V, Cyclone 10, Arria II are supported. @c Arria V and Arria 10, MAX II, MAX V, MAX10) -For the option @option{-family} @var{name} is one of @var{cycloneiii cycloneiv cyclonev cyclone10 arriaii}. -This is needed when the JTAG ID of the device is ambiguous (same ID is used for chips in different families). +The option @option{-family} @var{name} is one of @var{cycloneiii cycloneiv cyclonev cyclone10 arriaii}. As input file format the driver supports a '.rbf' (raw bitstream file) file. The '.rbf' file can be generated from a '.sof' file with @verb{|quartus_cpf -c blinker.sof blinker.rbf|} diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 799552901..1a4c4b774 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -760,8 +760,9 @@ static const struct command_registration jtag_subcommand_handlers[] = { .mode = COMMAND_EXEC, .handler = handle_jtag_configure, .help = "Return any Tcl handler for the specified " - "TAP event.", - .usage = "tap_name '-event' event_name", + "TAP event or the value of the IDCODE found in hardware.", + .usage = "tap_name '-event' event_name | " + "tap_name '-idcode'", }, { .name = "names", diff --git a/src/pld/intel.c b/src/pld/intel.c index fe85cd62c..a4bdabe26 100644 --- a/src/pld/intel.c +++ b/src/pld/intel.c @@ -37,142 +37,11 @@ struct intel_pld_device { enum intel_family_e family; }; -struct intel_device_parameters_elem { - uint32_t id; - unsigned int boundary_scan_length; - int checkpos; - enum intel_family_e family; -}; - -static const struct intel_device_parameters_elem intel_device_parameters[] = { - {0x020f10dd, 603, 226, INTEL_CYCLONEIII}, /* EP3C5 EP3C10 */ - {0x020f20dd, 1080, 409, INTEL_CYCLONEIII}, /* EP3C16 */ - {0x020f30dd, 732, 286, INTEL_CYCLONEIII}, /* EP3C25 */ - {0x020f40dd, 1632, 604, INTEL_CYCLONEIII}, /* EP3C40 */ - {0x020f50dd, 1164, 442, INTEL_CYCLONEIII}, /* EP3C55 */ - {0x020f60dd, 1314, 502, INTEL_CYCLONEIII}, /* EP3C80 */ - {0x020f70dd, 1620, 613, INTEL_CYCLONEIII}, /* EP3C120*/ - {0x027010dd, 1314, 226, INTEL_CYCLONEIII}, /* EP3CLS70 */ - {0x027000dd, 1314, 226, INTEL_CYCLONEIII}, /* EP3CLS100 */ - {0x027030dd, 1314, 409, INTEL_CYCLONEIII}, /* EP3CLS150 */ - {0x027020dd, 1314, 409, INTEL_CYCLONEIII}, /* EP3CLS200 */ - - {0x020f10dd, 603, 226, INTEL_CYCLONEIV}, /* EP4CE6 EP4CE10 */ - {0x020f20dd, 1080, 409, INTEL_CYCLONEIV}, /* EP4CE15 */ - {0x020f30dd, 732, 286, INTEL_CYCLONEIV}, /* EP4CE22 */ - {0x020f40dd, 1632, 604, INTEL_CYCLONEIV}, /* EP4CE30 EP4CE40 */ - {0x020f50dd, 1164, 442, INTEL_CYCLONEIV}, /* EP4CE55 */ - {0x020f60dd, 1314, 502, INTEL_CYCLONEIV}, /* EP4CE75 */ - {0x020f70dd, 1620, 613, INTEL_CYCLONEIV}, /* EP4CE115 */ - {0x028010dd, 260, 229, INTEL_CYCLONEIV}, /* EP4CGX15 */ - {0x028120dd, 494, 463, INTEL_CYCLONEIV}, /* EP4CGX22 */ - {0x028020dd, 494, 463, INTEL_CYCLONEIV}, /* EP4CGX30 */ - {0x028230dd, 1006, 943, INTEL_CYCLONEIV}, /* EP4CGX30 */ - {0x028130dd, 1006, 943, INTEL_CYCLONEIV}, /* EP4CGX50 */ - {0x028030dd, 1006, 943, INTEL_CYCLONEIV}, /* EP4CGX75 */ - {0x028140dd, 1495, 1438, INTEL_CYCLONEIV}, /* EP4CGX110 */ - {0x028040dd, 1495, 1438, INTEL_CYCLONEIV}, /* EP4CGX150 */ - - {0x02b150dd, 864, 163, INTEL_CYCLONEV}, /* 5CEBA2F23 5CEBA2F17 5CEFA2M13 5CEFA2F23 5CEBA2U15 5CEFA2U19 5CEBA2U19 */ - {0x02d020dd, 1485, 19, INTEL_CYCLONEV}, /* 5CSXFC6D6F31 5CSTFD6D5F31 5CSEBA6U23 5CSEMA6U23 5CSEBA6U19 5CSEBA6U23 - 5CSEBA6U19 5CSEMA6F31 5CSXFC6C6U23 */ - {0x02b040dd, 1728, -1, INTEL_CYCLONEV}, /* 5CGXFC9EF35 5CGXBC9AU19 5CGXBC9CF23 5CGTFD9CF23 5CGXFC9AU19 5CGXFC9CF23 - 5CGXFC9EF31 5CGXFC9DF27 5CGXBC9DF27 5CGXBC9EF31 5CGTFD9EF31 5CGTFD9EF35 - 5CGTFD9AU19 5CGXBC9EF35 5CGTFD9DF27 */ - {0x02b050dd, 864, 163, INTEL_CYCLONEV}, /* 5CEFA4U19 5CEFA4F23 5CEFA4M13 5CEBA4F17 5CEBA4U15 5CEBA4U19 5CEBA4F23 */ - {0x02b030dd, 1488, 19, INTEL_CYCLONEV}, /* 5CGXBC7CU19 5CGTFD7CU19 5CGTFD7DF27 5CGXFC7BM15 5CGXFC7DF27 5CGXFC7DF31 - 5CGTFD7CF23 5CGXBC7CF23 5CGXBC7DF31 5CGTFD7BM15 5CGXFC7CU19 5CGTFD7DF31 - 5CGXBC7BM15 5CGXFC7CF23 5CGXBC7DF27 */ - {0x02d120dd, 1485, -1, INTEL_CYCLONEV}, /* 5CSEBA5U23 5CSEBA5U23 5CSTFD5D5F31 5CSEBA5U19 5CSXFC5D6F31 5CSEMA5U23 - 5CSEMA5F31 5CSXFC5C6U23 5CSEBA5U19 */ - {0x02b220dd, 1104, 19, INTEL_CYCLONEV}, /* 5CEBA5U19 5CEFA5U19 5CEFA5M13 5CEBA5F23 5CEFA5F23 */ - {0x02b020dd, 1104, 19, INTEL_CYCLONEV}, /* 5CGXBC5CU19 5CGXFC5F6M11 5CGXFC5CM13 5CGTFD5CF23 5CGXBC5CF23 5CGTFD5CF27 - 5CGTFD5F5M11 5CGXFC5CF27 5CGXFC5CU19 5CGTFD5CM13 5CGXFC5CF23 5CGXBC5CF27 - 5CGTFD5CU19 */ - {0x02d010dd, 1197, -1, INTEL_CYCLONEV}, /* 5CSEBA4U23 5CSXFC4C6U23 5CSEMA4U23 5CSEBA4U23 5CSEBA4U19 5CSEBA4U19 - 5CSXFC2C6U23 */ - {0x02b120dd, 1104, 19, INTEL_CYCLONEV}, /* 5CGXFC4CM13 5CGXFC4CU19 5CGXFC4F6M11 5CGXBC4CU19 5CGXFC4CF27 5CGXBC4CF23 - 5CGXBC4CF27 5CGXFC4CF23 */ - {0x02b140dd, 1728, -1, INTEL_CYCLONEV}, /* 5CEFA9F31 5CEBA9F31 5CEFA9F27 5CEBA9U19 5CEBA9F27 5CEFA9U19 5CEBA9F23 - 5CEFA9F23 */ - {0x02b010dd, 720, 19, INTEL_CYCLONEV}, /* 5CGXFC3U15 5CGXBC3U15 5CGXFC3F23 5CGXFC3U19 5CGXBC3U19 5CGXBC3F23 */ - {0x02b130dd, 1488, 19, INTEL_CYCLONEV}, /* 5CEFA7F31 5CEBA7F27 5CEBA7M15 5CEFA7U19 5CEBA7F23 5CEFA7F23 5CEFA7F27 - 5CEFA7M15 5CEBA7U19 5CEBA7F31 */ - {0x02d110dd, 1197, -1, INTEL_CYCLONEV}, /* 5CSEBA2U23 5CSEMA2U23 5CSEBA2U23 5CSEBA2U19 5CSEBA2U19 */ - - {0x020f10dd, 603, 226, INTEL_CYCLONE10}, /* 10CL006E144 10CL006U256 10CL010M164 10CL010U256 10CL010E144 */ - {0x020f20dd, 1080, 409, INTEL_CYCLONE10}, /* 10CL016U256 10CL016E144 10CL016U484 10CL016F484 10CL016M164 */ - {0x020f30dd, 732, 286, INTEL_CYCLONE10}, /* 10CL025U256 10CL025E144 */ - {0x020f40dd, 1632, 604, INTEL_CYCLONE10}, /* 10CL040F484 10CL040U484 */ - {0x020f50dd, 1164, 442, INTEL_CYCLONE10}, /* 10CL055F484 10CL055U484 */ - {0x020f60dd, 1314, 502, INTEL_CYCLONE10}, /* 10CL080F484 10CL080F780 10CL080U484 */ - {0x020f70dd, 1620, 613, INTEL_CYCLONE10}, /* 10CL120F484 10CL120F780 */ - - {0x02e120dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX085U484 10CX085F672 */ - {0x02e320dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX105F780 10CX105U484 10CX105F672 */ - {0x02e720dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX150F672 10CX150F780 10CX150U484 */ - {0x02ef20dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX220F672 10CX220F780 10CX220U484 */ - - {0x025120dd, 1227, 1174, INTEL_ARRIAII}, /* EP2AGX45 */ - {0x025020dd, 1227, -1, INTEL_ARRIAII}, /* EP2AGX65 */ - {0x025130dd, 1467, -1, INTEL_ARRIAII}, /* EP2AGX95 */ - {0x025030dd, 1467, -1, INTEL_ARRIAII}, /* EP2AGX125 */ - {0x025140dd, 1971, -1, INTEL_ARRIAII}, /* EP2AGX190 */ - {0x025040dd, 1971, -1, INTEL_ARRIAII}, /* EP2AGX260 */ - {0x024810dd, 2274, -1, INTEL_ARRIAII}, /* EP2AGZ225 */ - {0x0240a0dd, 2682, -1, INTEL_ARRIAII}, /* EP2AGZ300 */ - {0x024820dd, 2682, -1, INTEL_ARRIAII}, /* EP2AGZ350 */ -}; - -static int intel_fill_device_parameters(struct intel_pld_device *intel_info) -{ - for (size_t i = 0; i < ARRAY_SIZE(intel_device_parameters); ++i) { - if (intel_device_parameters[i].id == intel_info->tap->idcode && - intel_info->family == intel_device_parameters[i].family) { - if (intel_info->boundary_scan_length == 0) - intel_info->boundary_scan_length = intel_device_parameters[i].boundary_scan_length; - - if (intel_info->checkpos == -1) - intel_info->checkpos = intel_device_parameters[i].checkpos; - - return ERROR_OK; - } - } - - return ERROR_FAIL; -} - -static int intel_check_for_unique_id(struct intel_pld_device *intel_info) -{ - int found = 0; - for (size_t i = 0; i < ARRAY_SIZE(intel_device_parameters); ++i) { - if (intel_device_parameters[i].id == intel_info->tap->idcode) { - ++found; - intel_info->family = intel_device_parameters[i].family; - } - } - - return (found == 1) ? ERROR_OK : ERROR_FAIL; -} - static int intel_check_config(struct intel_pld_device *intel_info) { - if (!intel_info->tap->has_idcode) { - LOG_ERROR("no IDCODE"); - return ERROR_FAIL; - } - - if (intel_info->family == INTEL_UNKNOWN) { - if (intel_check_for_unique_id(intel_info) != ERROR_OK) { - LOG_ERROR("id is ambiguous, please specify family"); + if (intel_info->boundary_scan_length == 0) { + LOG_ERROR("unknown boundary scan length. Please specify with 'intel set_bscan'."); return ERROR_FAIL; - } - } - - if (intel_info->boundary_scan_length == 0 || intel_info->checkpos == -1) { - int ret = intel_fill_device_parameters(intel_info); - if (ret != ERROR_OK) - return ret; } if (intel_info->checkpos >= 0 && (unsigned int)intel_info->checkpos >= intel_info->boundary_scan_length) { @@ -305,6 +174,8 @@ static int intel_load(struct pld_device *pld_device, const char *filename) LOG_ERROR("Check failed"); return ERROR_FAIL; } + } else { + LOG_INFO("unable to check. Please specify with position 'intel set_check_pos'."); } retval = intel_set_instr(tap, 0x003); @@ -417,7 +288,7 @@ COMMAND_HANDLER(intel_set_check_pos_command_handler) PLD_CREATE_COMMAND_HANDLER(intel_pld_create_command) { - if (CMD_ARGC != 4 && CMD_ARGC != 6) + if (CMD_ARGC != 6) return ERROR_COMMAND_SYNTAX_ERROR; if (strcmp(CMD_ARGV[2], "-chain-position") != 0) @@ -430,24 +301,23 @@ PLD_CREATE_COMMAND_HANDLER(intel_pld_create_command) } enum intel_family_e family = INTEL_UNKNOWN; - if (CMD_ARGC == 6) { - if (strcmp(CMD_ARGV[4], "-family") != 0) - return ERROR_COMMAND_SYNTAX_ERROR; - if (strcmp(CMD_ARGV[5], "cycloneiii") == 0) { - family = INTEL_CYCLONEIII; - } else if (strcmp(CMD_ARGV[5], "cycloneiv") == 0) { - family = INTEL_CYCLONEIV; - } else if (strcmp(CMD_ARGV[5], "cyclonev") == 0) { - family = INTEL_CYCLONEV; - } else if (strcmp(CMD_ARGV[5], "cyclone10") == 0) { - family = INTEL_CYCLONE10; - } else if (strcmp(CMD_ARGV[5], "arriaii") == 0) { - family = INTEL_ARRIAII; - } else { - command_print(CMD, "unknown family"); - return ERROR_FAIL; - } + if (strcmp(CMD_ARGV[4], "-family") != 0) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (strcmp(CMD_ARGV[5], "cycloneiii") == 0) { + family = INTEL_CYCLONEIII; + } else if (strcmp(CMD_ARGV[5], "cycloneiv") == 0) { + family = INTEL_CYCLONEIV; + } else if (strcmp(CMD_ARGV[5], "cyclonev") == 0) { + family = INTEL_CYCLONEV; + } else if (strcmp(CMD_ARGV[5], "cyclone10") == 0) { + family = INTEL_CYCLONE10; + } else if (strcmp(CMD_ARGV[5], "arriaii") == 0) { + family = INTEL_ARRIAII; + } else { + command_print(CMD, "unknown family"); + return ERROR_FAIL; } struct intel_pld_device *intel_info = malloc(sizeof(struct intel_pld_device)); diff --git a/tcl/fpga/altera-arriaii.cfg b/tcl/fpga/altera-arriaii.cfg index d59c18207..9cf680d5f 100644 --- a/tcl/fpga/altera-arriaii.cfg +++ b/tcl/fpga/altera-arriaii.cfg @@ -21,11 +21,26 @@ if { [info exists CHIPNAME] } { set _CHIPNAME arriaii } -jtag newtap $_CHIPNAME tap -irlen 10 \ - -expected-id 0x025120dd -expected-id 0x025040dd \ - -expected-id 0x025020dd -expected-id 0x024810dd \ - -expected-id 0x025130dd -expected-id 0x0240a0dd \ - -expected-id 0x025030dd -expected-id 0x024820dd \ - -expected-id 0x025140dd +array set _ARRIA_2_DATA { + 0x025120dd {1227 1174 EP2AGX45} + 0x025020dd {1227 -1 EP2AGX65} + 0x025130dd {1467 -1 EP2AGX95} + 0x025030dd {1467 -1 EP2AGX125} + 0x025140dd {1971 -1 EP2AGX190} + 0x025040dd {1971 -1 EP2AGX260} + 0x024810dd {2274 -1 EP2AGZ225} + 0x0240a0dd {2682 -1 EP2AGZ300} + 0x024820dd {2682 -1 EP2AGZ350} +} + +set jtag_newtap_cmd {jtag newtap $_CHIPNAME tap -irlen 10 -ignore-version} +foreach id [array names _ARRIA_2_DATA] { + set cmd [concat "-expected-id" id] +} +eval $jtag_newtap_cmd + +source [find fpga/altera_common_init.cfg] pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family arriaii +jtag configure $_CHIPNAME.tap -event setup "set_bscan_checkpos_on_setup $_CHIPNAME {$_ARRIA_2_DATA}" + diff --git a/tcl/fpga/altera-cyclone10.cfg b/tcl/fpga/altera-cyclone10.cfg index 3a1bc1f65..0898c74e1 100644 --- a/tcl/fpga/altera-cyclone10.cfg +++ b/tcl/fpga/altera-cyclone10.cfg @@ -4,31 +4,33 @@ # see: https://www.intel.com/content/www/us/en/docs/programmable/683777/current/bst-operation-control.html # and: https://www.intel.cn/content/dam/support/us/en/programmable/kdb/pdfs/literature/hb/cyclone-10/c10gx-51003.pdf -# GX085: 0x02e120dd -# GX105: 0x02e320dd -# GX150: 0x02e720dd -# GX220: 0x02ef20dd -# 10cl006: 0x020f10dd -# 10cl010: 0x020f10dd -# 10cl016: 0x020f20dd -# 10cl025: 0x020f30dd -# 10cl040: 0x020f40dd -# 10cl055: 0x020f50dd -# 10cl080: 0x020f60dd -# 10cl120: 0x020f70dd - if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME cyclone10 } -jtag newtap $_CHIPNAME tap -irlen 10 \ - -expected-id 0x02e720dd -expected-id 0x02e120dd \ - -expected-id 0x02ef20dd -expected-id 0x02e320dd \ - -expected-id 0x020f10dd -expected-id 0x020f20dd \ - -expected-id 0x020f30dd -expected-id 0x020f40dd \ - -expected-id 0x020f50dd -expected-id 0x020f60dd \ - -expected-id 0x020f70dd +array set _CYCLONE_10_DATA { + 0x020f10dd { 603 226 10cl006_10cl010} + 0x020f20dd {1080 409 10cl016} + 0x020f30dd { 732 286 10cl025} + 0x020f40dd {1632 604 10cl040} + 0x020f50dd {1164 442 10cl055} + 0x020f60dd {1314 502 10cl080} + 0x020f70dd {1620 613 10cl120} + 0x02e120dd {1339 -1 GX085} + 0x02e320dd {1339 -1 GX105} + 0x02e720dd {1339 -1 GX150} + 0x02ef20dd {1339 -1 GX220} +} -pld device intel $_CHIPNAME.tap cyclone10 +set jtag_newtap_cmd {jtag newtap $_CHIPNAME tap -irlen 10 -ignore-version} +foreach id [array names _CYCLONE_10_DATA] { + set cmd [concat "-expected-id" id] +} +eval $jtag_newtap_cmd + +source [find fpga/altera_common_init.cfg] + +pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cyclone10 +jtag configure $_CHIPNAME.tap -event setup "set_bscan_checkpos_on_setup $_CHIPNAME {$_CYCLONE_10_DATA}" diff --git a/tcl/fpga/altera-cycloneiii.cfg b/tcl/fpga/altera-cycloneiii.cfg index d9be6455d..b0da418c0 100644 --- a/tcl/fpga/altera-cycloneiii.cfg +++ b/tcl/fpga/altera-cycloneiii.cfg @@ -4,32 +4,33 @@ # see Cyclone III Device Handbook # Table 12-2: Device IDCODE for Cyclone III Device Family -#EP3C5 0x020f10dd -#EP3C10 0x020f10dd -#EP3C16 0x020f20dd -#EP3C25 0x020f30dd -#EP3C40 0x020f40dd -#EP3C55 0x020f50dd -#EP3C80 0x020f60dd -#EP3C120 0x020f70dd -#Cyclone III LS -#EP3CLS70 0x027010dd -#EP3CLS100 0x027000dd -#EP3CLS150 0x027030dd -#EP3CLS200 0x027020dd - if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME cycloneiii } -jtag newtap $_CHIPNAME tap -irlen 10 \ - -expected-id 0x020f10dd -expected-id 0x020f20dd \ - -expected-id 0x020f30dd -expected-id 0x020f40dd \ - -expected-id 0x020f50dd -expected-id 0x020f60dd \ - -expected-id 0x020f70dd -expected-id 0x027010dd \ - -expected-id 0x027000dd -expected-id 0x027030dd \ - -expected-id 0x027020dd +array set _CYCLONE_3_DATA { + 0x020f10dd { 603 226 EP3C5_EP3C10} + 0x020f20dd {1080 409 EP3C16} + 0x020f30dd { 732 286 EP3C25} + 0x020f40dd {1632 604 EP3C40} + 0x020f50dd {1164 442 EP3C55} + 0x020f60dd {1314 502 EP3C80} + 0x020f70dd {1620 613 EP3C120} + 0x027010dd {1314 226 EP3CLS70} + 0x027000dd {1314 226 EP3CLS100} + 0x027030dd {1314 409 EP3CLS150} + 0x027020dd {1314 409 EP3CLS200} +} + +set jtag_newtap_cmd {jtag newtap $_CHIPNAME tap -irlen 10 -ignore-version} +foreach id [array names _CYCLONE_3_DATA] { + set cmd [concat "-expected-id" id] +} +eval $jtag_newtap_cmd + +source [find fpga/altera_common_init.cfg] pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cycloneiii +jtag configure $_CHIPNAME.tap -event setup "set_bscan_checkpos_on_setup $_CHIPNAME {$_CYCLONE_3_DATA}" diff --git a/tcl/fpga/altera-cycloneiv.cfg b/tcl/fpga/altera-cycloneiv.cfg index 6a908e8af..44eb89dec 100644 --- a/tcl/fpga/altera-cycloneiv.cfg +++ b/tcl/fpga/altera-cycloneiv.cfg @@ -4,38 +4,37 @@ # see Cyclone IV Device Handbook # Table 10-2: IDCODE Information for 32-Bit Cyclone IV Devices -#EP4CE6 0x020f10dd -#EP4CE10 0x020f10dd -#EP4CE15 0x020f20dd -#EP4CE22 0x020f30dd -#EP4CE30 0x020f40dd -#EP4CE40 0x020f40dd -#EP4CE55 0x020f50dd -#EP4CE75 0x020f60dd -#EP4CE115 0x020f70dd -#EP4CGX15 0x028010dd -#EP4CGX22 0x028120dd -#EP4CGX30 (3) 0x028020dd -#EP4CGX30 (4) 0x028230dd -#EP4CGX50 0x028130dd -#EP4CGX75 0x028030dd -#EP4CGX110 0x028140dd -#EP4CGX150 0x028040dd - if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME cycloneiv } -jtag newtap $_CHIPNAME tap -irlen 10 \ - -expected-id 0x020f10dd -expected-id 0x020f20dd \ - -expected-id 0x020f30dd -expected-id 0x020f40dd \ - -expected-id 0x020f50dd -expected-id 0x020f60dd \ - -expected-id 0x020f70dd -expected-id 0x028010dd \ - -expected-id 0x028120dd -expected-id 0x028020dd \ - -expected-id 0x028230dd -expected-id 0x028130dd \ - -expected-id 0x028030dd -expected-id 0x028140dd \ - -expected-id 0x028040dd +array set _CYCLON_4_DATA { + 0x020f10dd { 603 226 EP4CE6_EP4CE10} + 0x020f20dd {1080 409 EP4CE15} + 0x020f30dd { 732 286 EP4CE22} + 0x020f40dd {1632 604 EP4CE30_EP4CE40} + 0x020f50dd {1164 442 EP4CE55} + 0x020f60dd {1314 502 EP4CE75} + 0x020f70dd {1620 613 EP4CE115} + 0x028010dd { 260 229 EP4CGX15} + 0x028120dd { 494 463 EP4CGX22} + 0x028020dd { 494 463 EP4CGX30} + 0x028230dd {1006 943 EP4CGX30} + 0x028130dd {1006 943 EP4CGX50} + 0x028030dd {1006 943 EP4CGX75} + 0x028140dd {1495 1438 EP4CGX110} + 0x028040dd {1495 1438 EP4CGX150} +} + +set jtag_newtap_cmd {jtag newtap $_CHIPNAME tap -irlen 10 -ignore-version} +foreach id [array names _CYCLON_4_DATA] { + set cmd [concat "-expected-id" id] +} +eval $jtag_newtap_cmd + +source [find fpga/altera_common_init.cfg] pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cycloneiv +jtag configure $_CHIPNAME.tap -event setup "set_bscan_checkpos_on_setup $_CHIPNAME {$_CYCLONE_4_DATA}" diff --git a/tcl/fpga/altera-cyclonev.cfg b/tcl/fpga/altera-cyclonev.cfg index 46532a556..8d19cd8de 100644 --- a/tcl/fpga/altera-cyclonev.cfg +++ b/tcl/fpga/altera-cyclonev.cfg @@ -4,44 +4,36 @@ # see Cyclone V Device Handbook # Table 9-1: IDCODE Information for Cyclone V Devices -#5CEA2 0x02b150dd -#5CEA4 0x02b050dd -#5CEA5 0x02b220dd -#5CEA7 0x02b130dd -#5CEA9 0x02b140dd -#5CGXC3 0x02b010dd -#5CGXC4 0x02b120dd -#5CGXC5 0x02b020dd -#5CGXC7 0x02b030dd -#5CGXC9 0x02b040dd -#5CGTD5 0x02b020dd -#5CGTD7 0x02b030dd -#5CGTD9 0x02b040dd -#5CSEA2 0x02d110dd -#5CSEA4 0x02d010dd -#5CSEA5 0x02d120dd -#5CSEA6 0x02d020dd -#5CSXC2 0x02d110dd -#5CSXC4 0x02d010dd -#5CSXC5 0x02d120dd -#5CSXC6 0x02d020dd -#5CSTD5 0x02d120dd -#5CSTD6 0x02d020dd - - if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME cyclonev } -jtag newtap $_CHIPNAME tap -irlen 10 \ - -expected-id 0x02b150dd -expected-id 0x02b050dd \ - -expected-id 0x02b220dd -expected-id 0x02b130dd \ - -expected-id 0x02b140dd -expected-id 0x02b010dd \ - -expected-id 0x02b120dd -expected-id 0x02b020dd \ - -expected-id 0x02b030dd -expected-id 0x02b040dd \ - -expected-id 0x02d110dd -expected-id 0x02d010dd \ - -expected-id 0x02d120dd -expected-id 0x02d020dd +array set _CYCLONE_5_DATA { + 0x02b150dd { 864 163 5CEA2} + 0x02d020dd {1485 19 5CSEA6_5CSXC6_5CSTD6} + 0x02b040dd {1728 -1 5CGXC9_5CGTD9} + 0x02b050dd { 864 163 5CEA4} + 0x02b030dd {1488 19 5CGXC7_5CGTD7} + 0x02d120dd {1485 -1 5CSEA5_5CSXC5_5CSTD5} + 0x02b220dd {1104 19 5CEA5} + 0x02b020dd {1104 19 5CGXC5_5CGTD5} + 0x02d010dd {1197 -1 5CSEA4_5CSXC4} + 0x02b120dd {1104 19 5CGXC4} + 0x02b140dd {1728 -1 5CEA9} + 0x02b010dd { 720 19 5CGXC3} + 0x02b130dd {1488 19 5CEA7} + 0x02d110dd {1197 -1 5CSEA2_5CSXC2} +} + +set jtag_newtap_cmd {jtag newtap $_CHIPNAME tap -irlen 10 -ignore-version} +foreach id [array names _CYCLONE_5_DATA] { + set cmd [concat "-expected-id" id] +} +eval $jtag_newtap_cmd + +source [find fpga/altera_common_init.cfg] pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cyclonev +jtag configure $_CHIPNAME.tap -event setup "set_bscan_checkpos_on_setup $_CHIPNAME {$_CYCLONE_5_DATA}" diff --git a/tcl/fpga/altera_common_init.cfg b/tcl/fpga/altera_common_init.cfg new file mode 100644 index 000000000..683a844cb --- /dev/null +++ b/tcl/fpga/altera_common_init.cfg @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +proc set_bscan_checkpos_on_setup {chipname data} { + set tapid_w_version [jtag cget $chipname.tap -idcode] + set version_mask 0x0fffffff + set tapid [format 0x%08x [expr {$tapid_w_version & $version_mask}]] + intel set_bscan $chipname.pld [lindex $data($tapid) 0] + intel set_check_pos $chipname.pld [lindex $data($tapid) 1] +} From bf4be566a7e7f510977533a0402716d92f208f95 Mon Sep 17 00:00:00 2001 From: Daniel Anselmi Date: Mon, 19 Feb 2024 23:22:19 +0100 Subject: [PATCH 28/47] pld: small documentation fixes. Change-Id: I969f51c38fc0c34c6bdba98b0e618d7f28ea4052 Signed-off-by: Daniel Anselmi Reviewed-on: https://review.openocd.org/c/openocd/+/8084 Reviewed-by: Antonio Borneo Tested-by: jenkins --- doc/openocd.texi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 03fa94466..e46e6004b 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -8799,8 +8799,8 @@ The file format must be inferred by the driver. @section PLD/FPGA Drivers, Options, and Commands -Drivers may support PLD-specific options to the @command{pld device} -definition command, and may also define commands usable only with +Drivers may support PLD-specific options to the @command{pld create} +command, and may also define commands usable only with that particular type of PLD. @deffn {FPGA Driver} {virtex2} [@option{-no_jstart}] @@ -8888,7 +8888,7 @@ For the option @option{-family} @var{name} is one of @var{trion|titanium}. @deffn {FPGA Driver} {intel} @option{-family} This driver can be used to load the bitstream into Intel (former Altera) FPGAs. -The families Cyclone III, Cyclone IV, Cyclone V, Cyclone 10, Arria II are supported. +The families Cyclone III, Cyclone IV, Cyclone V, Cyclone 10 and Arria II are supported. @c Arria V and Arria 10, MAX II, MAX V, MAX10) The option @option{-family} @var{name} is one of @var{cycloneiii cycloneiv cyclonev cyclone10 arriaii}. From 4892e32294c6ea4cf53251adb81dee4e85aee0b0 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 17 May 2024 21:27:24 +0200 Subject: [PATCH 29/47] target/cortex_m: allow poll quickly get out of TARGET_RESET state cortex_m_poll_one() detects reset testing S_RESET_ST sticky bit. If the signal comes unexpectedly, poll must return TARGET_RESET state. On the contrary in case of polling inside of an OpenOCD reset command, TARGET_RESET has been has already been set and we need to get out of it as quickly as possible. The original code needs 2 polls: the first clears S_RESET_ST and keeps TARGET_RESET state, the current TARGET_RUNNING or TARGET_HALTED is reflected as late as the second poll is done. Change the logic to keep in TARGET_RESET only when necessary. See also [1] Link: [1] 8284: tcl/target: ti_cc3220sf: Use halt for CC3320SF targets | https://review.openocd.org/c/openocd/+/8284 Fixes: https://sourceforge.net/p/openocd/tickets/360/ Signed-off-by: Tomas Vanek Change-Id: I759461e5f89ca48a6e16e4b4101570260421dba1 Reviewed-on: https://review.openocd.org/c/openocd/+/8285 Tested-by: jenkins Reviewed-by: Dhruva Gole --- src/target/cortex_m.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index c225b1aa9..7f62a6de2 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -931,8 +931,12 @@ static int cortex_m_poll_one(struct target *target) if (target->state != TARGET_RESET) { target->state = TARGET_RESET; LOG_TARGET_INFO(target, "external reset detected"); + /* In case of an unexpected S_RESET_ST set TARGET_RESET state + * and keep it until the next poll to allow its detection */ + return ERROR_OK; } - return ERROR_OK; + /* S_RESET_ST was expected (in a reset command). Continue processing + * to quickly get out of TARGET_RESET state */ } if (target->state == TARGET_RESET) { From c5358c84ad0d3e7497498e0457cec7785f72910a Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sun, 2 Jun 2024 14:39:36 +0100 Subject: [PATCH 30/47] target: Do not use LOG_USER() for error messages Use LOG_TARGET_ERROR() to print the error messages and additionally add a reference to the related target. Change-Id: I06722f3911ef4034fdd05dc9b0e2571b01b657a4 Signed-off-by: Marc Schink Reviewed-on: https://review.openocd.org/c/openocd/+/8314 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/target/target.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 7d4947a6e..1f4817d5c 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -2997,14 +2997,14 @@ static int handle_target(void *priv) target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); } if (target->backoff.times > 0) { - LOG_USER("Polling target %s failed, trying to reexamine", target_name(target)); + LOG_TARGET_ERROR(target, "Polling failed, trying to reexamine"); target_reset_examined(target); retval = target_examine_one(target); /* Target examination could have failed due to unstable connection, * but we set the examined flag anyway to repoll it later */ if (retval != ERROR_OK) { target_set_examined(target); - LOG_USER("Examination failed, GDB will be halted. Polling again in %dms", + LOG_TARGET_ERROR(target, "Examination failed, GDB will be halted. Polling again in %dms", target->backoff.times * polling_interval); return retval; } @@ -4691,9 +4691,8 @@ void target_handle_event(struct target *target, enum target_event e) if (retval != JIM_OK) { Jim_MakeErrorMessage(teap->interp); - LOG_USER("Error executing event %s on target %s:\n%s", + LOG_TARGET_ERROR(target, "Execution of event %s failed:\n%s", target_event_name(e), - target_name(target), Jim_GetString(Jim_GetResult(teap->interp), NULL)); /* clean both error code and stacktrace before return */ Jim_Eval(teap->interp, "error \"\" \"\""); From 91043cecee396209bd4d616fe6e78d835bebd978 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 13 May 2024 15:40:15 +0200 Subject: [PATCH 31/47] target: aarch64: align armv8_read_reg() and armv8_read_reg32() These functions are today always called with non-NULL parameter regval, so the actual check is not needed. Anyway, for any future code change, check the parameter at the entry of the functions and return error if it is not valid. Simplify the check to assign the result value and align the code of the two functions. Change-Id: Ie4d98063006d70d9e2bcfc00bc930133caf33515 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8266 Tested-by: jenkins --- src/target/armv8.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index bf582ff80..8d97902f5 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -282,6 +282,9 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv uint32_t value; uint64_t value_64; + if (!regval) + return ERROR_FAIL; + switch (regnum) { case 0 ... 30: retval = dpm->instr_read_data_dcc_64(dpm, @@ -361,10 +364,8 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv break; } - if (retval == ERROR_OK && regval) + if (retval == ERROR_OK) *regval = value_64; - else - retval = ERROR_FAIL; return retval; } @@ -512,6 +513,9 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re uint32_t value = 0; int retval; + if (!regval) + return ERROR_FAIL; + switch (regnum) { case ARMV8_R0 ... ARMV8_R14: /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */ @@ -587,7 +591,7 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re break; } - if (retval == ERROR_OK && regval) + if (retval == ERROR_OK) *regval = value; return retval; From bcd6a1022322f67f25f74af2dfe40d440d382e74 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 13 May 2024 17:20:52 +0200 Subject: [PATCH 32/47] target: armv8_dpm: silence error on register R/W The command 'gdb_report_register_access_error' is used to silence errors while reading registers and not reporting them to GDB. Nevertheless, the error is printed by a LOG_ERROR() in armv8_dpm. Change the message to LOG_DEBUG(). It will still cause the error to be propagated and eventually printed by the caller (e.g. by the command 'reg'). Change-Id: Ic0db74fa28235d686ddd21a5960c52ae003e0931 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8267 Tested-by: jenkins --- src/target/armv8_dpm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index 8bb24f225..271bd91c3 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -677,7 +677,7 @@ static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) } if (retval != ERROR_OK) - LOG_ERROR("Failed to read %s register", r->name); + LOG_DEBUG("Failed to read %s register", r->name); return retval; } @@ -719,7 +719,7 @@ static int dpmv8_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) } if (retval != ERROR_OK) - LOG_ERROR("Failed to write %s register", r->name); + LOG_DEBUG("Failed to write %s register", r->name); return retval; } From 8c75e4760333a4e0408bdf9dd58a702e4fb67c51 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 13 May 2024 18:19:55 +0200 Subject: [PATCH 33/47] target: aarch64: access reg ELR_EL3 only in EL3 The register ELR_EL3 is accessible and it's content is relevant only when the target is in EL3. Without this patch, an error: Error: Opcode 0xd53e4020, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $ELR_EL3 or through OpenOCD command reg ELR_EL3 Detect the EL and return error if the register cannot be accessed. Change-Id: I545abb196e5c34e462c7e5d5d3ec952e588642da Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8268 Tested-by: jenkins --- src/target/armv8.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/target/armv8.c b/src/target/armv8.c index 8d97902f5..e36e2f6f4 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -278,6 +278,7 @@ static int armv8_get_pauth_mask(struct armv8_common *armv8, uint64_t *mask) static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regval) { struct arm_dpm *dpm = &armv8->dpm; + unsigned int curel = armv8_curel_from_core_mode(dpm->arm->core_mode); int retval; uint32_t value; uint64_t value_64; @@ -322,6 +323,11 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv ARMV8_MRS(SYSTEM_ELR_EL2, 0), &value_64); break; case ARMV8_ELR_EL3: + if (curel < SYSTEM_CUREL_EL3) { + LOG_DEBUG("ELR_EL3 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_ELR_EL3, 0), &value_64); break; @@ -396,6 +402,7 @@ static int armv8_read_reg_simdfp_aarch64(struct armv8_common *armv8, int regnum, static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t value_64) { struct arm_dpm *dpm = &armv8->dpm; + unsigned int curel = armv8_curel_from_core_mode(dpm->arm->core_mode); int retval; uint32_t value; @@ -443,6 +450,11 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_ELR_EL2, 0), value_64); break; case ARMV8_ELR_EL3: + if (curel < SYSTEM_CUREL_EL3) { + LOG_DEBUG("ELR_EL3 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } retval = dpm->instr_write_data_r0_64(dpm, ARMV8_MSR_GP(SYSTEM_ELR_EL3, 0), value_64); break; From 230680916039ba413278b74f3440ffa49e55de27 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 May 2024 10:03:09 +0200 Subject: [PATCH 34/47] target: aarch64: access reg ESR_EL3 only in EL3 The register ESR_EL3 is accessible and it's content is relevant only when the target is in EL3. Plus, the register is 64 bits wide. Without this patch, an error: Error: Opcode 0xd53e5200, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $ESR_EL3 or through OpenOCD command reg ESR_EL3 Detect the EL and return error if the register cannot be accessed. Handle the register as 64 bits. Drop the FIXME comment on Aarch32 case, as the register exists in Aarch64 only. Change-Id: Ie8c69dc7b50ae81a52506cf151c8e64e15752d0d Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8269 Tested-by: jenkins --- src/target/armv8.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index e36e2f6f4..383ac3ef4 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -342,9 +342,13 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv value_64 = value; break; case ARMV8_ESR_EL3: - retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS(SYSTEM_ESR_EL3, 0), &value); - value_64 = value; + if (curel < SYSTEM_CUREL_EL3) { + LOG_DEBUG("ESR_EL3 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_read_data_r0_64(dpm, + ARMV8_MRS(SYSTEM_ESR_EL3, 0), &value_64); break; case ARMV8_SPSR_EL1: retval = dpm->instr_read_data_r0(dpm, @@ -469,9 +473,13 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_ESR_EL2, 0), value); break; case ARMV8_ESR_EL3: - value = value_64; - retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP(SYSTEM_ESR_EL3, 0), value); + if (curel < SYSTEM_CUREL_EL3) { + LOG_DEBUG("ESR_EL3 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_write_data_r0_64(dpm, + ARMV8_MSR_GP(SYSTEM_ESR_EL3, 0), value_64); break; case ARMV8_SPSR_EL1: value = value_64; @@ -575,7 +583,7 @@ static int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *re ARMV4_5_MRC(15, 4, 0, 5, 2, 0), &value); break; - case ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */ + case ARMV8_ESR_EL3: /* no equivalent in aarch32 */ retval = ERROR_FAIL; break; case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */ @@ -711,7 +719,7 @@ static int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t va ARMV4_5_MCR(15, 4, 0, 5, 2, 0), value); break; - case ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */ + case ARMV8_ESR_EL3: /* no equivalent in aarch32 */ retval = ERROR_FAIL; break; case ARMV8_SPSR_EL1: /* mapped to SPSR_svc */ @@ -1534,7 +1542,7 @@ static const struct { { ARMV8_ELR_EL3, "ELR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked", NULL}, - { ARMV8_ESR_EL3, "ESR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", + { ARMV8_ESR_EL3, "ESR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, { ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", NULL}, From 405e78771b7f2a09298b675e7fbd05803672416c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 May 2024 10:40:32 +0200 Subject: [PATCH 35/47] target: aarch64: access reg SPSR_EL3 only in EL3 The register SPSR_EL3 is accessible and it's content is relevant only when the target is in EL3. Plus, the register is 64 bits wide. Without this patch, an error: Error: Opcode 0xd53e4000, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $SPSR_EL3 or through OpenOCD command reg SPSR_EL3 Detect the EL and return error if the register cannot be accessed. Handle the register as 64 bits. Change-Id: I00849d99feeb96589c426fcafda98127dbd19a67 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8270 Tested-by: jenkins --- src/target/armv8.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index 383ac3ef4..e8c189c1c 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -361,9 +361,13 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv value_64 = value; break; case ARMV8_SPSR_EL3: - retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value); - value_64 = value; + if (curel < SYSTEM_CUREL_EL3) { + LOG_DEBUG("SPSR_EL3 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_read_data_r0_64(dpm, + ARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value_64); break; case ARMV8_PAUTH_CMASK: case ARMV8_PAUTH_DMASK: @@ -492,9 +496,13 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_SPSR_EL2, 0), value); break; case ARMV8_SPSR_EL3: - value = value_64; - retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP(SYSTEM_SPSR_EL3, 0), value); + if (curel < SYSTEM_CUREL_EL3) { + LOG_DEBUG("SPSR_EL3 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_write_data_r0_64(dpm, + ARMV8_MSR_GP(SYSTEM_SPSR_EL3, 0), value_64); break; default: retval = ERROR_FAIL; @@ -1544,7 +1552,7 @@ static const struct { NULL}, { ARMV8_ESR_EL3, "ESR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, - { ARMV8_SPSR_EL3, "SPSR_EL3", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", + { ARMV8_SPSR_EL3, "SPSR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, { ARMV8_PAUTH_DMASK, "pauth_dmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL}, { ARMV8_PAUTH_CMASK, "pauth_cmask", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, "org.gnu.gdb.aarch64.pauth", NULL}, From 190176a6bc947fd2516b959217084e531374b9bf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 May 2024 11:03:45 +0200 Subject: [PATCH 36/47] target: aarch64: access reg ELR_EL2 only in EL2 and EL3 The register ELR_EL2 is accessible and it's content is relevant only when the target is in EL2 or EL3. Virtualization SW in EL1 can also access it, but this either triggers a trap to EL2 or returns ELR_EL1. Debugger should not mix the real ELR_EL2 with the virtual register. Without this patch, an error: Error: Opcode 0xd53c4020, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $ELR_EL2 or through OpenOCD command reg ELR_EL2 Detect the EL and return error if the register cannot be accessed. Change-Id: Idf02b42a7339df83260c1e44ceabbb05fbf392b9 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8271 Tested-by: jenkins --- src/target/armv8.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/target/armv8.c b/src/target/armv8.c index e8c189c1c..a537d610c 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -319,6 +319,11 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv ARMV8_MRS(SYSTEM_ELR_EL1, 0), &value_64); break; case ARMV8_ELR_EL2: + if (curel < SYSTEM_CUREL_EL2) { + LOG_DEBUG("ELR_EL2 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_ELR_EL2, 0), &value_64); break; @@ -454,6 +459,11 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_ELR_EL1, 0), value_64); break; case ARMV8_ELR_EL2: + if (curel < SYSTEM_CUREL_EL2) { + LOG_DEBUG("ELR_EL2 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } retval = dpm->instr_write_data_r0_64(dpm, ARMV8_MSR_GP(SYSTEM_ELR_EL2, 0), value_64); break; From 766a84b79892c1321f3f86d3f1b301519269b4f5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 May 2024 12:07:58 +0200 Subject: [PATCH 37/47] target: aarch64: access reg ESR_EL2 only in EL2 and EL3 The register ESR_EL2 is accessible and it's content is relevant only when the target is in EL2 or EL3. Virtualization SW in EL1 can also access it, but this either triggers a trap to EL2 or returns ESR_EL1. Debugger should not mix the real ESR_EL2 with the virtual register. Plus, the register is 64 bits wide. Without this patch, an error: Error: Opcode 0xd53c5200, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $ESR_EL2 or through OpenOCD command reg ESR_EL2 Detect the EL and return error if the register cannot be accessed. Handle the register as 64 bits. Change-Id: Icb32b44886d50907f29b068ce61e4be8bed10208 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8272 Tested-by: jenkins --- src/target/armv8.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index a537d610c..49fcb7217 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -342,9 +342,13 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv value_64 = value; break; case ARMV8_ESR_EL2: - retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS(SYSTEM_ESR_EL2, 0), &value); - value_64 = value; + if (curel < SYSTEM_CUREL_EL2) { + LOG_DEBUG("ESR_EL2 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_read_data_r0_64(dpm, + ARMV8_MRS(SYSTEM_ESR_EL2, 0), &value_64); break; case ARMV8_ESR_EL3: if (curel < SYSTEM_CUREL_EL3) { @@ -482,9 +486,13 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_ESR_EL1, 0), value); break; case ARMV8_ESR_EL2: - value = value_64; - retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP(SYSTEM_ESR_EL2, 0), value); + if (curel < SYSTEM_CUREL_EL2) { + LOG_DEBUG("ESR_EL2 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_write_data_r0_64(dpm, + ARMV8_MSR_GP(SYSTEM_ESR_EL2, 0), value_64); break; case ARMV8_ESR_EL3: if (curel < SYSTEM_CUREL_EL3) { @@ -1553,7 +1561,7 @@ static const struct { { ARMV8_ELR_EL2, "ELR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked", NULL}, - { ARMV8_ESR_EL2, "ESR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", + { ARMV8_ESR_EL2, "ESR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, { ARMV8_SPSR_EL2, "SPSR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", NULL}, From 2a63fabd095044f0a05cf69a34300409809f676b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 May 2024 12:16:13 +0200 Subject: [PATCH 38/47] target: aarch64: access reg SPSR_EL2 only in EL2 and EL3 The register SPSR_EL2 is accessible and it's content is relevant only when the target is in EL2 or EL3. Virtualization SW in EL1 can also access it, but this either triggers a trap to EL2 or returns SPSR_EL1. Debugger should not mix the real SPSR_EL2 with the virtual register. Plus, the register is 64 bits wide. Without this patch, an error: Error: Opcode 0xd53c4000, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $SPSR_EL2 or through OpenOCD command reg SPSR_EL2 Detect the EL and return error if the register cannot be accessed. Handle the register as 64 bits. Change-Id: If3792296b36282c08d597dd46cfe044d6b8288ea Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8273 Tested-by: jenkins --- src/target/armv8.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index 49fcb7217..b622dc990 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -365,9 +365,13 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv value_64 = value; break; case ARMV8_SPSR_EL2: - retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS(SYSTEM_SPSR_EL2, 0), &value); - value_64 = value; + if (curel < SYSTEM_CUREL_EL2) { + LOG_DEBUG("SPSR_EL2 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_read_data_r0_64(dpm, + ARMV8_MRS(SYSTEM_SPSR_EL2, 0), &value_64); break; case ARMV8_SPSR_EL3: if (curel < SYSTEM_CUREL_EL3) { @@ -509,9 +513,13 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_SPSR_EL1, 0), value); break; case ARMV8_SPSR_EL2: - value = value_64; - retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP(SYSTEM_SPSR_EL2, 0), value); + if (curel < SYSTEM_CUREL_EL2) { + LOG_DEBUG("SPSR_EL2 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_write_data_r0_64(dpm, + ARMV8_MSR_GP(SYSTEM_SPSR_EL2, 0), value_64); break; case ARMV8_SPSR_EL3: if (curel < SYSTEM_CUREL_EL3) { @@ -1563,7 +1571,7 @@ static const struct { NULL}, { ARMV8_ESR_EL2, "ESR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, - { ARMV8_SPSR_EL2, "SPSR_EL2", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", + { ARMV8_SPSR_EL2, "SPSR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, { ARMV8_ELR_EL3, "ELR_EL3", 64, ARMV8_64_EL3H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked", From f39f136e012589212b463af4ef1ac7d855901810 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 May 2024 14:17:39 +0200 Subject: [PATCH 39/47] target: aarch64: access reg ELR_EL1 only in EL1, EL2 and EL3 The register ELR_EL1 is accessible and it's content is relevant only when the target is in EL1 or EL2 or EL3. Without this patch, an error: Error: Opcode 0xd5384020, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $ELR_EL1 or through OpenOCD command reg ELR_EL1 Detect the EL and return error if the register cannot be accessed. Change-Id: I402dda4cd9dae502b05572fc6c1a8f0edf349bb1 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8274 Tested-by: jenkins --- src/target/armv8.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/target/armv8.c b/src/target/armv8.c index b622dc990..176747013 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -315,6 +315,11 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv value_64 = value; break; case ARMV8_ELR_EL1: + if (curel < SYSTEM_CUREL_EL1) { + LOG_DEBUG("ELR_EL1 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_ELR_EL1, 0), &value_64); break; @@ -463,6 +468,11 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu break; /* registers clobbered by taking exception in debug state */ case ARMV8_ELR_EL1: + if (curel < SYSTEM_CUREL_EL1) { + LOG_DEBUG("ELR_EL1 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } retval = dpm->instr_write_data_r0_64(dpm, ARMV8_MSR_GP(SYSTEM_ELR_EL1, 0), value_64); break; From b5dfef7577f87c34bd397981c17e5d461d1c217f Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 May 2024 14:23:07 +0200 Subject: [PATCH 40/47] target: aarch64: access reg ESR_EL1 only in EL1, EL2 and EL3 The register ESR_EL1 is accessible and it's content is relevant only when the target is in EL1 or EL2 or EL3. Plus, the register is 64 bits wide. Without this patch, an error: Error: Opcode 0xd5385200, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $ESR_EL1 or through OpenOCD command reg ESR_EL1 Detect the EL and return error if the register cannot be accessed. Handle the register as 64 bits. Change-Id: Icd65470c279e5cfd03091db6435cdaa1c447644c Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8275 Tested-by: jenkins --- src/target/armv8.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index 176747013..14b172689 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -342,9 +342,13 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv ARMV8_MRS(SYSTEM_ELR_EL3, 0), &value_64); break; case ARMV8_ESR_EL1: - retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS(SYSTEM_ESR_EL1, 0), &value); - value_64 = value; + if (curel < SYSTEM_CUREL_EL1) { + LOG_DEBUG("ESR_EL1 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_read_data_r0_64(dpm, + ARMV8_MRS(SYSTEM_ESR_EL1, 0), &value_64); break; case ARMV8_ESR_EL2: if (curel < SYSTEM_CUREL_EL2) { @@ -495,9 +499,13 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_ELR_EL3, 0), value_64); break; case ARMV8_ESR_EL1: - value = value_64; - retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP(SYSTEM_ESR_EL1, 0), value); + if (curel < SYSTEM_CUREL_EL1) { + LOG_DEBUG("ESR_EL1 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_write_data_r0_64(dpm, + ARMV8_MSR_GP(SYSTEM_ESR_EL1, 0), value_64); break; case ARMV8_ESR_EL2: if (curel < SYSTEM_CUREL_EL2) { @@ -1572,7 +1580,7 @@ static const struct { { ARMV8_ELR_EL1, "ELR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked", NULL}, - { ARMV8_ESR_EL1, "ESR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", + { ARMV8_ESR_EL1, "ESR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, { ARMV8_SPSR_EL1, "SPSR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", NULL}, From 198fecf5e4b03c2024c9d75fd5e6045daf681ed5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 14 May 2024 14:40:07 +0200 Subject: [PATCH 41/47] target: aarch64: access reg SPSR_EL1 only in EL1, EL2 and EL3 The register SPSR_EL1 is accessible and it's content is relevant only when the target is in EL1 or EL2 or EL3. Plus, the register is 64 bits wide. Without this patch, an error: Error: Opcode 0xd5384000, DSCR.ERR=1, DSCR.EL=1 is triggered by GDB register window or through GDB command x/p $SPSR_EL1 or through OpenOCD command reg SPSR_EL1 Detect the EL and return error if the register cannot be accessed. Handle the register as 64 bits. Change-Id: Ia0f984d52920cc32b8ee31157d62c13dea616a3a Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8276 Tested-by: jenkins --- src/target/armv8.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index 14b172689..b54ef13d3 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -369,9 +369,13 @@ static int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regv ARMV8_MRS(SYSTEM_ESR_EL3, 0), &value_64); break; case ARMV8_SPSR_EL1: - retval = dpm->instr_read_data_r0(dpm, - ARMV8_MRS(SYSTEM_SPSR_EL1, 0), &value); - value_64 = value; + if (curel < SYSTEM_CUREL_EL1) { + LOG_DEBUG("SPSR_EL1 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_read_data_r0_64(dpm, + ARMV8_MRS(SYSTEM_SPSR_EL1, 0), &value_64); break; case ARMV8_SPSR_EL2: if (curel < SYSTEM_CUREL_EL2) { @@ -526,9 +530,13 @@ static int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t valu ARMV8_MSR_GP(SYSTEM_ESR_EL3, 0), value_64); break; case ARMV8_SPSR_EL1: - value = value_64; - retval = dpm->instr_write_data_r0(dpm, - ARMV8_MSR_GP(SYSTEM_SPSR_EL1, 0), value); + if (curel < SYSTEM_CUREL_EL1) { + LOG_DEBUG("SPSR_EL1 not accessible in EL%u", curel); + retval = ERROR_FAIL; + break; + } + retval = dpm->instr_write_data_r0_64(dpm, + ARMV8_MSR_GP(SYSTEM_SPSR_EL1, 0), value_64); break; case ARMV8_SPSR_EL2: if (curel < SYSTEM_CUREL_EL2) { @@ -1582,7 +1590,7 @@ static const struct { NULL}, { ARMV8_ESR_EL1, "ESR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, - { ARMV8_SPSR_EL1, "SPSR_EL1", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, "banked", "net.sourceforge.openocd.banked", + { ARMV8_SPSR_EL1, "SPSR_EL1", 64, ARMV8_64_EL1H, REG_TYPE_UINT64, "banked", "net.sourceforge.openocd.banked", NULL}, { ARMV8_ELR_EL2, "ELR_EL2", 64, ARMV8_64_EL2H, REG_TYPE_CODE_PTR, "banked", "net.sourceforge.openocd.banked", From dde096e03fa4912aa44b2b72cfbdb7676340a3d1 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 17 Sep 2023 11:15:22 +0200 Subject: [PATCH 42/47] itm: fix default initialization Commit f9509c92dba3 ("itm: rework itm commands before 'init'") ignores the default enable of ITM channel 0, that is applied when no 'itm port[s]' is issued. Call armv7m_trace_itm_config() unconditionally to handle it. Change-Id: I3e85d0b063ed38c1552f6af9ea9eea2e76aa9025 Signed-off-by: Antonio Borneo Reported-by: Paul Fertser Fixes: f9509c92dba3 ("itm: rework itm commands before 'init'") Reviewed-on: https://review.openocd.org/c/openocd/+/7900 Reviewed-by: Tested-by: jenkins --- src/target/armv7m_trace.c | 22 ++++++++++++++-------- src/target/armv7m_trace.h | 2 -- src/target/cortex_m.c | 4 ++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c index 45117d2db..556568d71 100644 --- a/src/target/armv7m_trace.c +++ b/src/target/armv7m_trace.c @@ -92,11 +92,14 @@ COMMAND_HANDLER(handle_itm_port_command) else armv7m->trace_config.itm_ter[reg_idx] &= ~(1 << port); - if (CMD_CTX->mode == COMMAND_EXEC) - return armv7m_trace_itm_config(target); + /* + * In config mode ITM is not accessible yet. + * Keep the value and it will be programmed at target init. + */ + if (CMD_CTX->mode == COMMAND_CONFIG) + return ERROR_OK; - armv7m->trace_config.itm_deferred_config = true; - return ERROR_OK; + return armv7m_trace_itm_config(target); } COMMAND_HANDLER(handle_itm_ports_command) @@ -112,11 +115,14 @@ COMMAND_HANDLER(handle_itm_ports_command) memset(armv7m->trace_config.itm_ter, enable ? 0xff : 0, sizeof(armv7m->trace_config.itm_ter)); - if (CMD_CTX->mode == COMMAND_EXEC) - return armv7m_trace_itm_config(target); + /* + * In config mode ITM is not accessible yet. + * Keep the value and it will be programmed at target init. + */ + if (CMD_CTX->mode == COMMAND_CONFIG) + return ERROR_OK; - armv7m->trace_config.itm_deferred_config = true; - return ERROR_OK; + return armv7m_trace_itm_config(target); } static const struct command_registration itm_command_handlers[] = { diff --git a/src/target/armv7m_trace.h b/src/target/armv7m_trace.h index 5abb0b940..02eca932d 100644 --- a/src/target/armv7m_trace.h +++ b/src/target/armv7m_trace.h @@ -35,8 +35,6 @@ struct armv7m_trace_config { bool itm_async_timestamps; /** Enable synchronisation packet transmission (for sync port only) */ bool itm_synchro_packets; - /** Config ITM after target examine */ - bool itm_deferred_config; }; extern const struct command_registration armv7m_trace_command_handlers[]; diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 7f62a6de2..34c7cd4d2 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2659,8 +2659,8 @@ int cortex_m_examine(struct target *target) if (retval != ERROR_OK) return retval; - if (armv7m->trace_config.itm_deferred_config) - armv7m_trace_itm_config(target); + /* Configure ITM */ + armv7m_trace_itm_config(target); /* NOTE: FPB and DWT are both optional. */ From 23ba602ca5be4a4c0841a178775bc82b3be0b38f Mon Sep 17 00:00:00 2001 From: Timur Golubovich Date: Fri, 7 Jun 2024 16:42:16 +0300 Subject: [PATCH 43/47] remote_bitbang: fix assertion failure for the cases when connection is abruptly terminated Changes affect the function remote_bitbang_fill_buf. When read_socket returns 0, socket reached EOF and there is no data to read. But if request was blocking, the caller expected some data. Such situations should be treated as ERROR. Change-Id: I02ed484e61fb776c1625f6e36ab14c85891939b2 Signed-off-by: Timur Golubovich Reviewed-on: https://review.openocd.org/c/openocd/+/8325 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Antonio Borneo --- src/jtag/drivers/remote_bitbang.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c index 53d2151fd..edd36f2e6 100644 --- a/src/jtag/drivers/remote_bitbang.c +++ b/src/jtag/drivers/remote_bitbang.c @@ -114,12 +114,18 @@ static int remote_bitbang_fill_buf(enum block_bool block) contiguous_available_space); if (first && block == BLOCK) socket_nonblock(remote_bitbang_fd); - first = false; if (count > 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) { + /* When read_socket returns 0, socket reached EOF and there is + * no data to read. But if request was blocking, the caller + * expected some data. Such situations should be treated as ERROR. */ + if (first && block == BLOCK) { + LOG_ERROR("remote_bitbang: socket closed by remote"); + return ERROR_FAIL; + } return ERROR_OK; } else if (count < 0) { #ifdef _WIN32 @@ -133,6 +139,7 @@ static int remote_bitbang_fill_buf(enum block_bool block) return ERROR_FAIL; } } + first = false; } return ERROR_OK; From 92e8823ebdb6d01b41bb5d79af49501d525acd1d Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sun, 2 Jun 2024 12:20:36 +0100 Subject: [PATCH 44/47] server/gdb: Use LOG_TARGET_xxx() to show target name The output "gdb port disabled" is confusing without reference to the target. Use LOG_TARGET_INFO() to output the target name. While at it, use LOG_TARGET_xxx() for all log statements where the target name is already used. Change-Id: I70b134145837db623e008a4a6c0be0008d9a0d87 Signed-off-by: Marc Schink Reviewed-on: https://review.openocd.org/c/openocd/+/8313 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/server/gdb_server.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 0ded8e440..58326f77b 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1067,15 +1067,15 @@ static int gdb_new_connection(struct connection *connection) target_state_name(target)); if (!target_was_examined(target)) { - LOG_ERROR("Target %s not examined yet, refuse gdb connection %d!", - target_name(target), gdb_connection->unique_index); + LOG_TARGET_ERROR(target, "Target not examined yet, refuse gdb connection %d!", + gdb_connection->unique_index); return ERROR_TARGET_NOT_EXAMINED; } gdb_actual_connections++; if (target->state != TARGET_HALTED) - LOG_WARNING("GDB connection %d on target %s not halted", - gdb_actual_connections, target_name(target)); + LOG_TARGET_WARNING(target, "GDB connection %d not halted", + gdb_actual_connections); /* DANGER! If we fail subsequently, we must remove this handler, * otherwise we occasionally see crashes as the timer can invoke the @@ -1102,9 +1102,8 @@ static int gdb_connection_closed(struct connection *connection) log_remove_callback(gdb_log_callback, connection); gdb_actual_connections--; - LOG_DEBUG("{%d} GDB Close, Target: %s, state: %s, gdb_actual_connections=%d", + LOG_TARGET_DEBUG(target, "{%d} GDB Close, state: %s, gdb_actual_connections=%d", gdb_connection->unique_index, - target_name(target), target_state_name(target), gdb_actual_connections); @@ -2350,7 +2349,7 @@ static int smp_reg_list_noread(struct target *target, } } if (!found) { - LOG_DEBUG("[%s] %s not found in combined list", target_name(target), a->name); + LOG_TARGET_DEBUG(target, "%s not found in combined list", a->name); if (local_list_size >= combined_allocated) { combined_allocated *= 2; local_list = realloc(local_list, combined_allocated * sizeof(struct reg *)); @@ -2398,9 +2397,8 @@ static int smp_reg_list_noread(struct target *target, } } if (!found) { - LOG_WARNING("Register %s does not exist in %s, which is part of an SMP group where " - "this register does exist.", - a->name, target_name(head->target)); + LOG_TARGET_WARNING(head->target, "Register %s does not exist, which is part of an SMP group where " + "this register does exist.", a->name); } } free(reg_list); @@ -3012,17 +3010,17 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p /* simple case, a continue packet */ if (parse[0] == 'c') { gdb_running_type = 'c'; - LOG_DEBUG("target %s continue", target_name(target)); + LOG_TARGET_DEBUG(target, "target continue"); gdb_connection->output_flag = GDB_OUTPUT_ALL; retval = target_resume(target, 1, 0, 0, 0); if (retval == ERROR_TARGET_NOT_HALTED) - LOG_INFO("target %s was not halted when resume was requested", target_name(target)); + LOG_TARGET_INFO(target, "target was not halted when resume was requested"); /* poll target in an attempt to make its internal state consistent */ if (retval != ERROR_OK) { retval = target_poll(target); if (retval != ERROR_OK) - LOG_DEBUG("error polling target %s after failed resume", target_name(target)); + LOG_TARGET_DEBUG(target, "error polling target after failed resume"); } /* @@ -3100,7 +3098,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p } } - LOG_DEBUG("target %s single-step thread %"PRIx64, target_name(ct), thread_id); + LOG_TARGET_DEBUG(ct, "single-step thread %" PRIx64, thread_id); gdb_connection->output_flag = GDB_OUTPUT_ALL; target_call_event_callbacks(ct, TARGET_EVENT_GDB_START); @@ -3142,13 +3140,13 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p retval = target_step(ct, current_pc, 0, 0); if (retval == ERROR_TARGET_NOT_HALTED) - LOG_INFO("target %s was not halted when step was requested", target_name(ct)); + LOG_TARGET_INFO(ct, "target was not halted when step was requested"); /* if step was successful send a reply back to gdb */ if (retval == ERROR_OK) { retval = target_poll(ct); if (retval != ERROR_OK) - LOG_DEBUG("error polling target %s after successful step", target_name(ct)); + LOG_TARGET_DEBUG(ct, "error polling target after successful step"); /* send back signal information */ gdb_signal_reply(ct, connection); /* stop forwarding log packets! */ @@ -3839,7 +3837,7 @@ static int gdb_target_start(struct target *target, const char *port) if (!gdb_service) return -ENOMEM; - LOG_INFO("starting gdb server for %s on %s", target_name(target), port); + LOG_TARGET_INFO(target, "starting gdb server on %s", port); gdb_service->target = target; gdb_service->core[0] = -1; @@ -3867,20 +3865,20 @@ static int gdb_target_add_one(struct target *target) /* skip targets that cannot handle a gdb connections (e.g. mem_ap) */ if (!target_supports_gdb_connection(target)) { - LOG_DEBUG("skip gdb server for target %s", target_name(target)); + LOG_TARGET_DEBUG(target, "skip gdb server"); return ERROR_OK; } if (target->gdb_port_override) { if (strcmp(target->gdb_port_override, "disabled") == 0) { - LOG_INFO("gdb port disabled"); + LOG_TARGET_INFO(target, "gdb port disabled"); return ERROR_OK; } return gdb_target_start(target, target->gdb_port_override); } if (strcmp(gdb_port_next, "disabled") == 0) { - LOG_INFO("gdb port disabled"); + LOG_TARGET_INFO(target, "gdb port disabled"); return ERROR_OK; } From 6b984a54c9a44780729c85e44f60a1d0ae8d3932 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 14 Jun 2024 18:12:03 +0200 Subject: [PATCH 45/47] Remove '_s' suffix from structs Change-Id: I956acce316e60252b317daa41274403d87f704b8 Signed-off-by: Marc Schink Reviewed-on: https://review.openocd.org/c/openocd/+/8340 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Antonio Borneo --- src/jtag/drivers/nulink_usb.c | 60 +++++----- src/jtag/drivers/rlink.c | 6 +- src/jtag/drivers/stlink_usb.c | 206 ++++++++++++++++----------------- src/jtag/drivers/ti_icdi_usb.c | 36 +++--- src/jtag/hla/hla_interface.c | 2 +- src/jtag/hla/hla_interface.h | 6 +- src/jtag/hla/hla_layout.c | 6 +- src/jtag/hla/hla_layout.h | 22 ++-- src/target/hla_target.c | 28 ++--- 9 files changed, 186 insertions(+), 186 deletions(-) diff --git a/src/jtag/drivers/nulink_usb.c b/src/jtag/drivers/nulink_usb.c index 4fdb85782..66cf25a6d 100644 --- a/src/jtag/drivers/nulink_usb.c +++ b/src/jtag/drivers/nulink_usb.c @@ -34,7 +34,7 @@ #define NULINK2_USB_PID1 (0x5200) #define NULINK2_USB_PID2 (0x5201) -struct nulink_usb_handle_s { +struct nulink_usb_handle { hid_device *dev_handle; uint16_t max_packet_size; uint8_t usbcmdidx; @@ -87,7 +87,7 @@ enum nulink_connect { static int nulink_usb_xfer_rw(void *handle, uint8_t *buf) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -107,7 +107,7 @@ static int nulink_usb_xfer_rw(void *handle, uint8_t *buf) static int nulink1_usb_xfer(void *handle, uint8_t *buf, int size) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -120,7 +120,7 @@ static int nulink1_usb_xfer(void *handle, uint8_t *buf, int size) static int nulink2_usb_xfer(void *handle, uint8_t *buf, int size) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -133,7 +133,7 @@ static int nulink2_usb_xfer(void *handle, uint8_t *buf, int size) static void nulink1_usb_init_buffer(void *handle, uint32_t size) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; h->cmdidx = 0; @@ -149,7 +149,7 @@ static void nulink1_usb_init_buffer(void *handle, uint32_t size) static void nulink2_usb_init_buffer(void *handle, uint32_t size) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; h->cmdidx = 0; @@ -165,7 +165,7 @@ static void nulink2_usb_init_buffer(void *handle, uint32_t size) static inline int nulink_usb_xfer(void *handle, uint8_t *buf, int size) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -174,7 +174,7 @@ static inline int nulink_usb_xfer(void *handle, uint8_t *buf, int size) static inline void nulink_usb_init_buffer(void *handle, uint32_t size) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -183,7 +183,7 @@ static inline void nulink_usb_init_buffer(void *handle, uint32_t size) static int nulink_usb_version(void *handle) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_version"); @@ -219,7 +219,7 @@ static int nulink_usb_version(void *handle) static int nulink_usb_idcode(void *handle, uint32_t *idcode) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_idcode"); @@ -243,7 +243,7 @@ static int nulink_usb_idcode(void *handle, uint32_t *idcode) static int nulink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_write_debug_reg 0x%08" PRIX32 " 0x%08" PRIX32, addr, val); @@ -278,7 +278,7 @@ static int nulink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) static enum target_state nulink_usb_state(void *handle) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -299,7 +299,7 @@ static enum target_state nulink_usb_state(void *handle) static int nulink_usb_assert_srst(void *handle, int srst) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_assert_srst"); @@ -324,7 +324,7 @@ static int nulink_usb_assert_srst(void *handle, int srst) static int nulink_usb_reset(void *handle) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_reset"); @@ -349,7 +349,7 @@ static int nulink_usb_reset(void *handle) static int nulink_usb_run(void *handle) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_run"); @@ -365,7 +365,7 @@ static int nulink_usb_run(void *handle) static int nulink_usb_halt(void *handle) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_halt"); @@ -385,7 +385,7 @@ static int nulink_usb_halt(void *handle) static int nulink_usb_step(void *handle) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_step"); @@ -405,7 +405,7 @@ static int nulink_usb_step(void *handle) static int nulink_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -444,7 +444,7 @@ static int nulink_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val) static int nulink_usb_write_reg(void *handle, unsigned int regsel, uint32_t val) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -483,7 +483,7 @@ static int nulink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, int res = ERROR_OK; uint32_t offset = 0; uint32_t bytes_remaining = 12; - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_read_mem8: addr 0x%08" PRIx32 ", len %" PRId16, addr, len); @@ -568,7 +568,7 @@ static int nulink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, int res = ERROR_OK; uint32_t offset = 0; uint32_t bytes_remaining = 12; - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_write_mem8: addr 0x%08" PRIx32 ", len %" PRIu16, addr, len); @@ -675,7 +675,7 @@ static int nulink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, { int res = ERROR_OK; uint32_t bytes_remaining = 12; - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -744,7 +744,7 @@ static int nulink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, { int res = ERROR_OK; uint32_t bytes_remaining = 12; - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; assert(handle); @@ -819,7 +819,7 @@ static int nulink_usb_read_mem(void *handle, uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer) { int retval = ERROR_OK; - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; /* calculate byte count */ count *= size; @@ -879,7 +879,7 @@ static int nulink_usb_write_mem(void *handle, uint32_t addr, uint32_t size, uint32_t count, const uint8_t *buffer) { int retval = ERROR_OK; - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; if (addr < ARM_SRAM_BASE) { LOG_DEBUG("nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\n"); @@ -950,7 +950,7 @@ static int nulink_usb_override_target(const char *targetname) static int nulink_speed(void *handle, int khz, bool query) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; unsigned long max_ice_clock = khz; LOG_DEBUG("nulink_speed: query %s", query ? "yes" : "no"); @@ -1004,7 +1004,7 @@ static int nulink_speed(void *handle, int khz, bool query) static int nulink_usb_close(void *handle) { - struct nulink_usb_handle_s *h = handle; + struct nulink_usb_handle *h = handle; LOG_DEBUG("nulink_usb_close"); @@ -1018,7 +1018,7 @@ static int nulink_usb_close(void *handle) return ERROR_OK; } -static int nulink_usb_open(struct hl_interface_param_s *param, void **fd) +static int nulink_usb_open(struct hl_interface_param *param, void **fd) { struct hid_device_info *devs, *cur_dev; uint16_t target_vid = 0; @@ -1040,7 +1040,7 @@ static int nulink_usb_open(struct hl_interface_param_s *param, void **fd) return ERROR_FAIL; } - struct nulink_usb_handle_s *h = calloc(1, sizeof(*h)); + struct nulink_usb_handle *h = calloc(1, sizeof(*h)); if (!h) { LOG_ERROR("Out of memory"); goto error_open; @@ -1154,7 +1154,7 @@ error_open: return ERROR_FAIL; } -struct hl_layout_api_s nulink_usb_layout_api = { +struct hl_layout_api nulink_usb_layout_api = { .open = nulink_usb_open, .close = nulink_usb_close, .idcode = nulink_usb_idcode, diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c index 1b1f2e4de..afdf16e58 100644 --- a/src/jtag/drivers/rlink.c +++ b/src/jtag/drivers/rlink.c @@ -286,13 +286,13 @@ static uint8_t dtc_entry_download; static int dtc_load_from_buffer(struct libusb_device_handle *hdev_param, const uint8_t *buffer, size_t length) { - struct header_s { + struct header { uint8_t type; uint8_t length; }; int usb_err; - struct header_s *header; + struct header *header; uint8_t lut_start = 0xc0; dtc_entry_download = 0; @@ -311,7 +311,7 @@ static int dtc_load_from_buffer(struct libusb_device_handle *hdev_param, const u exit(1); } - header = (struct header_s *)buffer; + header = (struct header *)buffer; buffer += sizeof(*header); length -= sizeof(*header); diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index b14fbf1f3..8cf3b0c73 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -140,7 +140,7 @@ struct stlink_usb_version { uint32_t flags; }; -struct stlink_usb_priv_s { +struct stlink_usb_priv { /** */ struct libusb_device_handle *fd; /** */ @@ -154,7 +154,7 @@ struct stlink_tcp_version { uint32_t build; }; -struct stlink_tcp_priv_s { +struct stlink_tcp_priv { /** */ int fd; /** */ @@ -171,9 +171,9 @@ struct stlink_tcp_priv_s { struct stlink_tcp_version version; }; -struct stlink_backend_s { +struct stlink_backend { /** */ - int (*open)(void *handle, struct hl_interface_param_s *param); + int (*open)(void *handle, struct hl_interface_param *param); /** */ int (*close)(void *handle); /** */ @@ -245,13 +245,13 @@ struct dap_queue { }; /** */ -struct stlink_usb_handle_s { +struct stlink_usb_handle { /** */ - struct stlink_backend_s *backend; + struct stlink_backend *backend; /** */ union { - struct stlink_usb_priv_s usb_backend_priv; - struct stlink_tcp_priv_s tcp_backend_priv; + struct stlink_usb_priv usb_backend_priv; + struct stlink_tcp_priv tcp_backend_priv; }; /** */ uint8_t rx_ep; @@ -294,22 +294,22 @@ struct stlink_usb_handle_s { }; /** */ -static inline int stlink_usb_open(void *handle, struct hl_interface_param_s *param) +static inline int stlink_usb_open(void *handle, struct hl_interface_param *param) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; return h->backend->open(handle, param); } /** */ static inline int stlink_usb_close(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; return h->backend->close(handle); } /** */ static inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, int size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; return h->backend->xfer_noerrcheck(handle, buf, size); } @@ -567,7 +567,7 @@ static int stlink_usb_open_ap(void *handle, unsigned short apsel); /** */ static unsigned int stlink_usb_block(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -727,7 +727,7 @@ static int jtag_libusb_bulk_transfer_n( /** */ static int stlink_usb_xfer_v1_get_status(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int tr, ret; assert(handle); @@ -762,7 +762,7 @@ static int stlink_usb_xfer_v1_get_status(void *handle) #ifdef USE_LIBUSB_ASYNCIO static int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -800,7 +800,7 @@ static int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int #else static int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int tr, ret; assert(handle); @@ -834,7 +834,7 @@ static int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int static int stlink_usb_xfer_v1_get_sense(void *handle) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -860,7 +860,7 @@ static int stlink_usb_xfer_v1_get_sense(void *handle) /** */ static int stlink_usb_usb_read_trace(void *handle, const uint8_t *buf, int size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int tr, ret; ret = jtag_libusb_bulk_read(h->usb_backend_priv.fd, h->trace_ep, (char *)buf, size, @@ -882,7 +882,7 @@ static int stlink_usb_usb_read_trace(void *handle, const uint8_t *buf, int size) static int stlink_usb_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, int size) { int err, cmdsize = STLINK_CMD_SIZE_V2; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -915,7 +915,7 @@ static int stlink_usb_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, int static int stlink_tcp_send_cmd(void *handle, int send_size, int recv_size, bool check_tcp_status) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -980,7 +980,7 @@ static int stlink_tcp_send_cmd(void *handle, int send_size, int recv_size, bool /** */ static int stlink_tcp_xfer_noerrcheck(void *handle, const uint8_t *buf, int size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int send_size = STLINK_TCP_USB_CMD_SIZE; int recv_size = STLINK_TCP_SS_SIZE; @@ -1040,7 +1040,7 @@ static int stlink_tcp_xfer_noerrcheck(void *handle, const uint8_t *buf, int size /** */ static int stlink_tcp_read_trace(void *handle, const uint8_t *buf, int size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; stlink_usb_init_buffer(h, h->trace_ep, 0); return stlink_tcp_xfer_noerrcheck(handle, buf, size); @@ -1052,7 +1052,7 @@ static int stlink_tcp_read_trace(void *handle, const uint8_t *buf, int size) */ static int stlink_usb_error_check(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1162,7 +1162,7 @@ static int stlink_cmd_allow_retry(void *handle, const uint8_t *buf, int size) { int retries = 0; int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; while (1) { if ((h->st_mode != STLINK_MODE_DEBUG_SWIM) || !retries) { @@ -1191,7 +1191,7 @@ static int stlink_cmd_allow_retry(void *handle, const uint8_t *buf, int size) /** */ static int stlink_usb_read_trace(void *handle, const uint8_t *buf, int size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1206,14 +1206,14 @@ static int stlink_usb_read_trace(void *handle, const uint8_t *buf, int size) */ static void stlink_usb_set_cbw_transfer_datalength(void *handle, uint32_t size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; buf_set_u32(h->cmdbuf+8, 0, 32, size); } static void stlink_usb_xfer_v1_create_cmd(void *handle, uint8_t direction, uint32_t size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; /* fill the send buffer */ strcpy((char *)h->cmdbuf, "USBC"); @@ -1234,7 +1234,7 @@ static void stlink_usb_xfer_v1_create_cmd(void *handle, uint8_t direction, uint3 /** */ static void stlink_usb_init_buffer(void *handle, uint8_t direction, uint32_t size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; h->direction = direction; @@ -1256,7 +1256,7 @@ static int stlink_usb_version(void *handle) uint8_t v, x, y, jtag, swim, msd, bridge = 0; char v_str[5 * (1 + 3) + 1]; /* VvJjMmBbSs */ char *p; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1479,7 +1479,7 @@ static int stlink_usb_version(void *handle) static int stlink_usb_check_voltage(void *handle, float *target_voltage) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; uint32_t adc_results[2]; /* no error message, simply quit with error */ @@ -1511,7 +1511,7 @@ static int stlink_usb_check_voltage(void *handle, float *target_voltage) static int stlink_usb_set_swdclk(void *handle, uint16_t clk_divisor) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1535,7 +1535,7 @@ static int stlink_usb_set_swdclk(void *handle, uint16_t clk_divisor) static int stlink_usb_set_jtagclk(void *handle, uint16_t clk_divisor) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1561,7 +1561,7 @@ static int stlink_usb_set_jtagclk(void *handle, uint16_t clk_divisor) static int stlink_usb_current_mode(void *handle, uint8_t *mode) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1583,7 +1583,7 @@ static int stlink_usb_current_mode(void *handle, uint8_t *mode) static int stlink_usb_mode_enter(void *handle, enum stlink_mode type) { int rx_size = 0; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1631,7 +1631,7 @@ static int stlink_usb_mode_enter(void *handle, enum stlink_mode type) static int stlink_usb_mode_leave(void *handle, enum stlink_mode type) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1725,7 +1725,7 @@ static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int init int res; uint8_t mode; enum stlink_mode emode; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -1829,7 +1829,7 @@ static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int init /* request status from last swim request */ static int stlink_swim_status(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; stlink_usb_init_buffer(handle, h->rx_ep, 4); @@ -1849,7 +1849,7 @@ static int stlink_swim_status(void *handle) __attribute__((unused)) static int stlink_swim_cap(void *handle, uint8_t *cap) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; stlink_usb_init_buffer(handle, h->rx_ep, 8); @@ -1866,7 +1866,7 @@ static int stlink_swim_cap(void *handle, uint8_t *cap) /* debug dongle assert/deassert sreset line */ static int stlink_swim_assert_reset(void *handle, int reset) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; stlink_usb_init_buffer(handle, h->rx_ep, 0); @@ -1887,7 +1887,7 @@ static int stlink_swim_assert_reset(void *handle, int reset) */ static int stlink_swim_enter(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; stlink_usb_init_buffer(handle, h->rx_ep, 0); @@ -1902,7 +1902,7 @@ static int stlink_swim_enter(void *handle) /* switch high/low speed swim */ static int stlink_swim_speed(void *handle, int speed) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; stlink_usb_init_buffer(handle, h->rx_ep, 0); @@ -1924,7 +1924,7 @@ static int stlink_swim_speed(void *handle, int speed) */ static int stlink_swim_generate_rst(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; stlink_usb_init_buffer(handle, h->rx_ep, 0); @@ -1943,7 +1943,7 @@ static int stlink_swim_generate_rst(void *handle) */ static int stlink_swim_resync(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; stlink_usb_init_buffer(handle, h->rx_ep, 0); @@ -1957,7 +1957,7 @@ static int stlink_swim_resync(void *handle) static int stlink_swim_writebytes(void *handle, uint32_t addr, uint32_t len, const uint8_t *data) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; unsigned int i; unsigned int datalen = 0; @@ -1993,7 +1993,7 @@ static int stlink_swim_writebytes(void *handle, uint32_t addr, uint32_t len, con static int stlink_swim_readbytes(void *handle, uint32_t addr, uint32_t len, uint8_t *data) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; if (len > STLINK_SWIM_DATA_SIZE) @@ -2024,7 +2024,7 @@ static int stlink_swim_readbytes(void *handle, uint32_t addr, uint32_t len, uint static int stlink_usb_idcode(void *handle, uint32_t *idcode) { int res, offset; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2061,7 +2061,7 @@ static int stlink_usb_idcode(void *handle, uint32_t *idcode) static int stlink_usb_v2_read_debug_reg(void *handle, uint32_t addr, uint32_t *val) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int res; assert(handle); @@ -2083,7 +2083,7 @@ static int stlink_usb_v2_read_debug_reg(void *handle, uint32_t addr, uint32_t *v static int stlink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2105,7 +2105,7 @@ static int stlink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) /** */ static int stlink_usb_trace_read(void *handle, uint8_t *buf, size_t *size) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2156,7 +2156,7 @@ static enum target_state stlink_usb_v2_get_status(void *handle) static enum target_state stlink_usb_state(void *handle) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2198,7 +2198,7 @@ static enum target_state stlink_usb_state(void *handle) static int stlink_usb_assert_srst(void *handle, int srst) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2221,7 +2221,7 @@ static int stlink_usb_assert_srst(void *handle, int srst) static void stlink_usb_trace_disable(void *handle) { int res = ERROR_OK; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2243,7 +2243,7 @@ static void stlink_usb_trace_disable(void *handle) static int stlink_usb_trace_enable(void *handle) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2274,7 +2274,7 @@ static int stlink_usb_trace_enable(void *handle) /** */ static int stlink_usb_reset(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int retval; assert(handle); @@ -2304,7 +2304,7 @@ static int stlink_usb_reset(void *handle) static int stlink_usb_run(void *handle) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2326,7 +2326,7 @@ static int stlink_usb_run(void *handle) static int stlink_usb_halt(void *handle) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2347,7 +2347,7 @@ static int stlink_usb_halt(void *handle) /** */ static int stlink_usb_step(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2371,7 +2371,7 @@ static int stlink_usb_step(void *handle) static int stlink_usb_read_regs(void *handle) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2396,7 +2396,7 @@ static int stlink_usb_read_regs(void *handle) static int stlink_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2436,7 +2436,7 @@ static int stlink_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val) /** */ static int stlink_usb_write_reg(void *handle, unsigned int regsel, uint32_t val) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2465,7 +2465,7 @@ static int stlink_usb_write_reg(void *handle, unsigned int regsel, uint32_t val) static int stlink_usb_get_rw_status(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2490,7 +2490,7 @@ static int stlink_usb_read_mem8(void *handle, uint8_t ap_num, uint32_t csw, { int res; uint16_t read_len = len; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2534,7 +2534,7 @@ static int stlink_usb_write_mem8(void *handle, uint8_t ap_num, uint32_t csw, uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2572,7 +2572,7 @@ static int stlink_usb_read_mem16(void *handle, uint8_t ap_num, uint32_t csw, uint32_t addr, uint16_t len, uint8_t *buffer) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2620,7 +2620,7 @@ static int stlink_usb_write_mem16(void *handle, uint8_t ap_num, uint32_t csw, uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2666,7 +2666,7 @@ static int stlink_usb_read_mem32(void *handle, uint8_t ap_num, uint32_t csw, uint32_t addr, uint16_t len, uint8_t *buffer) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2711,7 +2711,7 @@ static int stlink_usb_write_mem32(void *handle, uint8_t ap_num, uint32_t csw, uint32_t addr, uint16_t len, const uint8_t *buffer) { int res; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -2752,7 +2752,7 @@ static int stlink_usb_write_mem32(void *handle, uint8_t ap_num, uint32_t csw, static int stlink_usb_read_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_t csw, uint32_t addr, uint16_t len, uint8_t *buffer) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle != NULL); @@ -2794,7 +2794,7 @@ static int stlink_usb_read_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_ static int stlink_usb_write_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_t csw, uint32_t addr, uint16_t len, const uint8_t *buffer) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle != NULL); @@ -2845,7 +2845,7 @@ static int stlink_usb_read_ap_mem(void *handle, uint8_t ap_num, uint32_t csw, int retval = ERROR_OK; uint32_t bytes_remaining; int retries = 0; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; /* calculate byte count */ count *= size; @@ -2930,7 +2930,7 @@ static int stlink_usb_write_ap_mem(void *handle, uint8_t ap_num, uint32_t csw, int retval = ERROR_OK; uint32_t bytes_remaining; int retries = 0; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; /* calculate byte count */ count *= size; @@ -3080,7 +3080,7 @@ static int stlink_match_speed_map(const struct speed_map *map, unsigned int map_ static int stlink_speed_swd(void *handle, int khz, bool query) { int speed_index; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; /* old firmware cannot change it */ if (!(h->version.flags & STLINK_F_HAS_SWD_SET_FREQ)) @@ -3103,7 +3103,7 @@ static int stlink_speed_swd(void *handle, int khz, bool query) static int stlink_speed_jtag(void *handle, int khz, bool query) { int speed_index; - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; /* old firmware cannot change it */ if (!(h->version.flags & STLINK_F_HAS_JTAG_SET_FREQ)) @@ -3135,7 +3135,7 @@ static void stlink_dump_speed_map(const struct speed_map *map, unsigned int map_ static int stlink_get_com_freq(void *handle, bool is_jtag, struct speed_map *map) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int i; if (h->version.jtag_api != STLINK_JTAG_API_V3) { @@ -3170,7 +3170,7 @@ static int stlink_get_com_freq(void *handle, bool is_jtag, struct speed_map *map static int stlink_set_com_freq(void *handle, bool is_jtag, unsigned int frequency) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; if (h->version.jtag_api != STLINK_JTAG_API_V3) { LOG_ERROR("Unknown command"); @@ -3191,7 +3191,7 @@ static int stlink_set_com_freq(void *handle, bool is_jtag, unsigned int frequenc static int stlink_speed_v3(void *handle, bool is_jtag, int khz, bool query) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int speed_index; struct speed_map map[STLINK_V3_MAX_FREQ_NB]; @@ -3211,7 +3211,7 @@ static int stlink_speed_v3(void *handle, bool is_jtag, int khz, bool query) static int stlink_speed(void *handle, int khz, bool query) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; if (!handle) return khz; @@ -3241,7 +3241,7 @@ static int stlink_speed(void *handle, int khz, bool query) /** */ static int stlink_usb_usb_close(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; if (!h) return ERROR_OK; @@ -3262,7 +3262,7 @@ static int stlink_usb_usb_close(void *handle) /** */ static int stlink_tcp_close(void *handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; if (!h) return ERROR_OK; @@ -3295,7 +3295,7 @@ static int stlink_tcp_close(void *handle) static int stlink_close(void *handle) { if (handle) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; stlink_usb_close(handle); @@ -3385,9 +3385,9 @@ static char *stlink_usb_get_alternate_serial(struct libusb_device_handle *device } /** */ -static int stlink_usb_usb_open(void *handle, struct hl_interface_param_s *param) +static int stlink_usb_usb_open(void *handle, struct hl_interface_param *param) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int err, retry_count = 1; h->cmdbuf = malloc(STLINK_SG_SIZE); @@ -3496,9 +3496,9 @@ static int stlink_usb_usb_open(void *handle, struct hl_interface_param_s *param) } /** */ -static int stlink_tcp_open(void *handle, struct hl_interface_param_s *param) +static int stlink_tcp_open(void *handle, struct hl_interface_param *param) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int ret; /* SWIM is not supported using stlink-server */ @@ -3711,27 +3711,27 @@ static int stlink_tcp_open(void *handle, struct hl_interface_param_s *param) return stlink_usb_version(h); } -static struct stlink_backend_s stlink_usb_backend = { +static struct stlink_backend stlink_usb_backend = { .open = stlink_usb_usb_open, .close = stlink_usb_usb_close, .xfer_noerrcheck = stlink_usb_usb_xfer_noerrcheck, .read_trace = stlink_usb_usb_read_trace, }; -static struct stlink_backend_s stlink_tcp_backend = { +static struct stlink_backend stlink_tcp_backend = { .open = stlink_tcp_open, .close = stlink_tcp_close, .xfer_noerrcheck = stlink_tcp_xfer_noerrcheck, .read_trace = stlink_tcp_read_trace, }; -static int stlink_open(struct hl_interface_param_s *param, enum stlink_mode mode, void **fd) +static int stlink_open(struct hl_interface_param *param, enum stlink_mode mode, void **fd) { - struct stlink_usb_handle_s *h; + struct stlink_usb_handle *h; LOG_DEBUG("stlink_open"); - h = calloc(1, sizeof(struct stlink_usb_handle_s)); + h = calloc(1, sizeof(struct stlink_usb_handle)); if (!h) { LOG_DEBUG("malloc failed"); @@ -3829,7 +3829,7 @@ error_open: return ERROR_FAIL; } -static int stlink_usb_hl_open(struct hl_interface_param_s *param, void **fd) +static int stlink_usb_hl_open(struct hl_interface_param *param, void **fd) { return stlink_open(param, stlink_get_mode(param->transport), fd); } @@ -3839,7 +3839,7 @@ static int stlink_config_trace(void *handle, bool enabled, unsigned int *trace_freq, unsigned int traceclkin_freq, uint16_t *prescaler) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; if (!(h->version.flags & STLINK_F_HAS_TRACE)) { LOG_ERROR("The attached ST-LINK version doesn't support trace"); @@ -3900,7 +3900,7 @@ static int stlink_config_trace(void *handle, bool enabled, /** */ static int stlink_usb_init_access_port(void *handle, unsigned char ap_num) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -3919,7 +3919,7 @@ static int stlink_usb_init_access_port(void *handle, unsigned char ap_num) /** */ static int stlink_usb_close_access_port(void *handle, unsigned char ap_num) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -3942,7 +3942,7 @@ static int stlink_usb_close_access_port(void *handle, unsigned char ap_num) static int stlink_usb_rw_misc_out(void *handle, uint32_t items, const uint8_t *buffer) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; unsigned int buflen = ALIGN_UP(items, 4) + 4 * items; LOG_DEBUG_IO("%s(%" PRIu32 ")", __func__, items); @@ -3963,7 +3963,7 @@ static int stlink_usb_rw_misc_out(void *handle, uint32_t items, const uint8_t *b static int stlink_usb_rw_misc_in(void *handle, uint32_t items, uint8_t *buffer) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; unsigned int buflen = 2 * 4 * items; LOG_DEBUG_IO("%s(%" PRIu32 ")", __func__, items); @@ -3991,7 +3991,7 @@ static int stlink_usb_rw_misc_in(void *handle, uint32_t items, uint8_t *buffer) static int stlink_read_dap_register(void *handle, unsigned short dap_port, unsigned short addr, uint32_t *val) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int retval; assert(handle); @@ -4015,7 +4015,7 @@ static int stlink_read_dap_register(void *handle, unsigned short dap_port, static int stlink_write_dap_register(void *handle, unsigned short dap_port, unsigned short addr, uint32_t val) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; assert(handle); @@ -4033,7 +4033,7 @@ static int stlink_write_dap_register(void *handle, unsigned short dap_port, } /** */ -struct hl_layout_api_s stlink_usb_layout_api = { +struct hl_layout_api stlink_usb_layout_api = { /** */ .open = stlink_usb_hl_open, /** */ @@ -4078,8 +4078,8 @@ struct hl_layout_api_s stlink_usb_layout_api = { * DAP direct interface */ -static struct stlink_usb_handle_s *stlink_dap_handle; -static struct hl_interface_param_s stlink_dap_param; +static struct stlink_usb_handle *stlink_dap_handle; +static struct hl_interface_param stlink_dap_param; static DECLARE_BITMAP(opened_ap, DP_APSEL_MAX + 1); static uint32_t last_csw_default[DP_APSEL_MAX + 1]; static int stlink_dap_error = ERROR_OK; @@ -4107,7 +4107,7 @@ static int stlink_dap_get_error(void) static int stlink_usb_open_ap(void *handle, unsigned short apsel) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; int retval; /* nothing to do on old versions */ @@ -4523,7 +4523,7 @@ static int stlink_usb_buf_rw_segment(void *handle, const struct dap_queue *q, un static int stlink_usb_count_misc_rw_queue(void *handle, const struct dap_queue *q, unsigned int len, unsigned int *pkt_items) { - struct stlink_usb_handle_s *h = handle; + struct stlink_usb_handle *h = handle; unsigned int i, items = 0; uint32_t ap_num = DP_APSEL_INVALID; unsigned int misc_max_items = (h->version.stlink == 2) ? STLINK_V2_RW_MISC_SIZE : STLINK_V3_RW_MISC_SIZE; @@ -5039,7 +5039,7 @@ COMMAND_HANDLER(stlink_dap_backend_command) COMMAND_HANDLER(stlink_dap_cmd_command) { unsigned int rx_n, tx_n; - struct stlink_usb_handle_s *h = stlink_dap_handle; + struct stlink_usb_handle *h = stlink_dap_handle; if (CMD_ARGC < 2) return ERROR_COMMAND_SYNTAX_ERROR; diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c index 4260e2d39..0e01171ea 100644 --- a/src/jtag/drivers/ti_icdi_usb.c +++ b/src/jtag/drivers/ti_icdi_usb.c @@ -33,7 +33,7 @@ #define PACKET_START "$" #define PACKET_END "#" -struct icdi_usb_handle_s { +struct icdi_usb_handle { struct libusb_device_handle *usb_dev; char *read_buffer; @@ -108,7 +108,7 @@ static int remote_unescape_input(const char *buffer, int len, char *out_buf, int static int icdi_send_packet(void *handle, int len) { unsigned char cksum = 0; - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; int result, retry = 0; int transferred = 0; @@ -220,7 +220,7 @@ static int icdi_send_packet(void *handle, int len) static int icdi_send_cmd(void *handle, const char *cmd) { - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; int cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "%s", cmd); return icdi_send_packet(handle, cmd_len); @@ -228,7 +228,7 @@ static int icdi_send_cmd(void *handle, const char *cmd) static int icdi_send_remote_cmd(void *handle, const char *data) { - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,"); cmd_len += hexify(h->write_buffer + cmd_len, (const uint8_t *)data, @@ -239,7 +239,7 @@ static int icdi_send_remote_cmd(void *handle, const char *data) static int icdi_get_cmd_result(void *handle) { - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; int offset = 0; char ch; @@ -284,7 +284,7 @@ static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) static enum target_state icdi_usb_state(void *handle) { int result; - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; uint32_t dhcsr; uint8_t buf[4]; @@ -303,7 +303,7 @@ static enum target_state icdi_usb_state(void *handle) static int icdi_usb_version(void *handle) { - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; char version[20]; @@ -335,7 +335,7 @@ static int icdi_usb_query(void *handle) { int result; - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; result = icdi_send_cmd(handle, "qSupported"); if (result != ERROR_OK) @@ -468,7 +468,7 @@ static int icdi_usb_read_regs(void *handle) static int icdi_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val) { int result; - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; char cmd[10]; snprintf(cmd, sizeof(cmd), "p%x", regsel); @@ -521,7 +521,7 @@ static int icdi_usb_write_reg(void *handle, unsigned int regsel, uint32_t val) static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer) { int result; - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; char cmd[20]; snprintf(cmd, sizeof(cmd), "x%" PRIx32 ",%" PRIx32, addr, len); @@ -549,7 +549,7 @@ static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint static int icdi_usb_write_mem_int(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer) { int result; - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%" PRIx32 ",%" PRIx32 ":", addr, len); @@ -581,7 +581,7 @@ static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer) { int retval = ERROR_OK; - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; uint32_t bytes_remaining; /* calculate byte count */ @@ -609,7 +609,7 @@ static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size, uint32_t count, const uint8_t *buffer) { int retval = ERROR_OK; - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; uint32_t bytes_remaining; /* calculate byte count */ @@ -640,7 +640,7 @@ static int icdi_usb_override_target(const char *targetname) static int icdi_usb_close(void *handle) { - struct icdi_usb_handle_s *h = handle; + struct icdi_usb_handle *h = handle; if (!h) return ERROR_OK; @@ -654,15 +654,15 @@ static int icdi_usb_close(void *handle) return ERROR_OK; } -static int icdi_usb_open(struct hl_interface_param_s *param, void **fd) +static int icdi_usb_open(struct hl_interface_param *param, void **fd) { /* TODO: Convert remaining libusb_ calls to jtag_libusb_ */ int retval; - struct icdi_usb_handle_s *h; + struct icdi_usb_handle *h; LOG_DEBUG("icdi_usb_open"); - h = calloc(1, sizeof(struct icdi_usb_handle_s)); + h = calloc(1, sizeof(struct icdi_usb_handle)); if (!h) { LOG_ERROR("unable to allocate memory"); @@ -743,7 +743,7 @@ error_open: return ERROR_FAIL; } -struct hl_layout_api_s icdi_usb_layout_api = { +struct hl_layout_api icdi_usb_layout_api = { .open = icdi_usb_open, .close = icdi_usb_close, .idcode = icdi_usb_idcode, diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 9c8d0fade..6ac680128 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -23,7 +23,7 @@ #include -static struct hl_interface_s hl_if = { +static struct hl_interface hl_if = { .param = { .device_desc = NULL, .vid = { 0 }, diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h index fa4965806..c95638b92 100644 --- a/src/jtag/hla/hla_interface.h +++ b/src/jtag/hla/hla_interface.h @@ -20,7 +20,7 @@ extern const char *hl_transports[]; #define HLA_MAX_USB_IDS 16 -struct hl_interface_param_s { +struct hl_interface_param { /** */ const char *device_desc; /** List of recognised VIDs */ @@ -39,9 +39,9 @@ struct hl_interface_param_s { uint16_t stlink_tcp_port; }; -struct hl_interface_s { +struct hl_interface { /** */ - struct hl_interface_param_s param; + struct hl_interface_param param; /** */ const struct hl_layout *layout; /** */ diff --git a/src/jtag/hla/hla_layout.c b/src/jtag/hla/hla_layout.c index 51671d60a..04c963f0e 100644 --- a/src/jtag/hla/hla_layout.c +++ b/src/jtag/hla/hla_layout.c @@ -21,7 +21,7 @@ #include #include -static int hl_layout_open(struct hl_interface_s *adapter) +static int hl_layout_open(struct hl_interface *adapter) { int res; @@ -39,7 +39,7 @@ static int hl_layout_open(struct hl_interface_s *adapter) return ERROR_OK; } -static int hl_layout_close(struct hl_interface_s *adapter) +static int hl_layout_close(struct hl_interface *adapter) { return ERROR_OK; } @@ -78,7 +78,7 @@ const struct hl_layout *hl_layout_get_list(void) return hl_layouts; } -int hl_layout_init(struct hl_interface_s *adapter) +int hl_layout_init(struct hl_interface *adapter) { LOG_DEBUG("hl_layout_init"); diff --git a/src/jtag/hla/hla_layout.h b/src/jtag/hla/hla_layout.h index e13da6531..71a7563e1 100644 --- a/src/jtag/hla/hla_layout.h +++ b/src/jtag/hla/hla_layout.h @@ -15,18 +15,18 @@ #include /** */ -struct hl_interface_s; -struct hl_interface_param_s; +struct hl_interface; +struct hl_interface_param; /** */ -extern struct hl_layout_api_s stlink_usb_layout_api; -extern struct hl_layout_api_s icdi_usb_layout_api; -extern struct hl_layout_api_s nulink_usb_layout_api; +extern struct hl_layout_api stlink_usb_layout_api; +extern struct hl_layout_api icdi_usb_layout_api; +extern struct hl_layout_api nulink_usb_layout_api; /** */ -struct hl_layout_api_s { +struct hl_layout_api { /** */ - int (*open)(struct hl_interface_param_s *param, void **handle); + int (*open)(struct hl_interface_param *param, void **handle); /** */ int (*close)(void *handle); /** */ @@ -121,16 +121,16 @@ struct hl_layout { /** */ char *name; /** */ - int (*open)(struct hl_interface_s *adapter); + int (*open)(struct hl_interface *adapter); /** */ - int (*close)(struct hl_interface_s *adapter); + int (*close)(struct hl_interface *adapter); /** */ - struct hl_layout_api_s *api; + struct hl_layout_api *api; }; /** */ const struct hl_layout *hl_layout_get_list(void); /** */ -int hl_layout_init(struct hl_interface_s *adapter); +int hl_layout_init(struct hl_interface *adapter); #endif /* OPENOCD_JTAG_HLA_HLA_LAYOUT_H */ diff --git a/src/target/hla_target.c b/src/target/hla_target.c index c1bda996c..d6f2afb4e 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -36,7 +36,7 @@ #define ARMV7M_SCS_DCRSR DCB_DCRSR #define ARMV7M_SCS_DCRDR DCB_DCRDR -static inline struct hl_interface_s *target_to_adapter(struct target *target) +static inline struct hl_interface *target_to_adapter(struct target *target) { return target->tap->priv; } @@ -44,14 +44,14 @@ static inline struct hl_interface_s *target_to_adapter(struct target *target) static int adapter_load_core_reg_u32(struct target *target, uint32_t regsel, uint32_t *value) { - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); return adapter->layout->api->read_reg(adapter->handle, regsel, value); } static int adapter_store_core_reg_u32(struct target *target, uint32_t regsel, uint32_t value) { - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); return adapter->layout->api->write_reg(adapter->handle, regsel, value); } @@ -65,7 +65,7 @@ static int adapter_examine_debug_reason(struct target *target) return ERROR_OK; } -static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl) +static int hl_dcc_read(struct hl_interface *hl_if, uint8_t *value, uint8_t *ctrl) { uint16_t dcrdr; int retval = hl_if->layout->api->read_mem(hl_if->handle, @@ -90,7 +90,7 @@ static int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ct static int hl_target_request_data(struct target *target, uint32_t size, uint8_t *buffer) { - struct hl_interface_s *hl_if = target_to_adapter(target); + struct hl_interface *hl_if = target_to_adapter(target); uint8_t data; uint8_t ctrl; uint32_t i; @@ -113,7 +113,7 @@ static int hl_handle_target_request(void *priv) if (!target_was_examined(target)) return ERROR_OK; - struct hl_interface_s *hl_if = target_to_adapter(target); + struct hl_interface *hl_if = target_to_adapter(target); if (!target->dbg_msg_enabled) return ERROR_OK; @@ -227,7 +227,7 @@ static int adapter_load_context(struct target *target) static int adapter_debug_entry(struct target *target) { - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); struct armv7m_common *armv7m = target_to_armv7m(target); struct arm *arm = &armv7m->arm; struct reg *r; @@ -286,7 +286,7 @@ static int adapter_debug_entry(struct target *target) static int adapter_poll(struct target *target) { enum target_state state; - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); struct armv7m_common *armv7m = target_to_armv7m(target); enum target_state prev_target_state = target->state; @@ -329,7 +329,7 @@ static int adapter_poll(struct target *target) static int hl_assert_reset(struct target *target) { int res = ERROR_OK; - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); struct armv7m_common *armv7m = target_to_armv7m(target); bool use_srst_fallback = true; @@ -412,7 +412,7 @@ static int hl_deassert_reset(struct target *target) static int adapter_halt(struct target *target) { int res; - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); LOG_DEBUG("%s", __func__); @@ -439,7 +439,7 @@ static int adapter_resume(struct target *target, int current, int debug_execution) { int res; - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); struct armv7m_common *armv7m = target_to_armv7m(target); uint32_t resume_pc; struct breakpoint *breakpoint = NULL; @@ -529,7 +529,7 @@ static int adapter_step(struct target *target, int current, target_addr_t address, int handle_breakpoints) { int res; - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); struct armv7m_common *armv7m = target_to_armv7m(target); struct breakpoint *breakpoint = NULL; struct reg *pc = armv7m->arm.pc; @@ -593,7 +593,7 @@ static int adapter_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) { - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); if (!count || !buffer) return ERROR_COMMAND_SYNTAX_ERROR; @@ -608,7 +608,7 @@ static int adapter_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { - struct hl_interface_s *adapter = target_to_adapter(target); + struct hl_interface *adapter = target_to_adapter(target); if (!count || !buffer) return ERROR_COMMAND_SYNTAX_ERROR; From 67be8188bb0625246f37347fa98e0f90bda1ad7a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 15 Jun 2024 17:57:25 +0200 Subject: [PATCH 46/47] Remove other '_s' suffix from structs Most of the work is already done by [1]. Remove few more '_s' suffix and also fix some comment referring to the old name of the struct. Link: https://review.openocd.org/c/openocd/+/8340 Change-Id: Ifddc401c3b05e62ece3aa7926af1e78f0c4a671e Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/8341 Reviewed-by: zapb Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/core.h | 10 +++++----- src/flash/nor/driver.h | 8 ++++---- src/flash/nor/pic32mx.c | 2 +- src/jtag/commands.h | 6 +++--- src/target/xtensa/xtensa.c | 2 +- src/target/xtensa/xtensa.h | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h index 80911f799..ff175a132 100644 --- a/src/flash/nor/core.h +++ b/src/flash/nor/core.h @@ -32,18 +32,18 @@ struct flash_sector { uint32_t size; /** * Indication of erasure status: 0 = not erased, 1 = erased, - * other = unknown. Set by @c flash_driver_s::erase_check only. + * other = unknown. Set by @c flash_driver::erase_check only. * * This information must be considered stale immediately. - * Don't set it in flash_driver_s::erase or a device mass_erase - * Don't clear it in flash_driver_s::write + * Don't set it in flash_driver::erase or a device mass_erase + * Don't clear it in flash_driver::write * The flag is not used in a protection block */ int is_erased; /** * Indication of protection status: 0 = unprotected/unlocked, * 1 = protected/locked, other = unknown. Set by - * @c flash_driver_s::protect_check. + * @c flash_driver::protect_check. * * This information must be considered stale immediately. * A million things could make it stale: power cycle, @@ -67,7 +67,7 @@ struct flash_sector { * a major interface. * * This structure will be passed as a parameter to the callbacks in the - * flash_driver_s structure, some of which may modify the contents of + * flash_driver structure, some of which may modify the contents of * this structure of the area of flash that it defines. Driver writers * may use the @c driver_priv member to store additional data on a * per-bank basis, if required. diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index 7d6f8c5cc..211661e21 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -29,7 +29,7 @@ struct flash_bank; * flash bank DRIVERNAME ...parameters... * @endcode * - * OpenOCD will search for the driver with a @c flash_driver_s::name + * OpenOCD will search for the driver with a @c flash_driver::name * that matches @c DRIVERNAME. * * The flash subsystem calls some of the other drivers routines a using @@ -170,7 +170,7 @@ struct flash_driver { /** * Check the erasure status of a flash bank. * When called, the driver routine must perform the required - * checks and then set the @c flash_sector_s::is_erased field + * checks and then set the @c flash_sector::is_erased field * for each of the flash banks's sectors. * * @param bank The bank to check @@ -182,7 +182,7 @@ struct flash_driver { * Determine if the specific bank is "protected" or not. * When called, the driver routine must must perform the * required protection check(s) and then set the @c - * flash_sector_s::is_protected field for each of the flash + * flash_sector::is_protected field for each of the flash * bank's sectors. * * If protection is not implemented, set method to NULL @@ -204,7 +204,7 @@ struct flash_driver { int (*info)(struct flash_bank *bank, struct command_invocation *cmd); /** - * A more gentle flavor of flash_driver_s::probe, performing + * A more gentle flavor of flash_driver::probe, performing * setup with less noise. Generally, driver routines should test * to see if the bank has already been probed; if it has, the * driver probably should not perform its probe a second time. diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c index 0f3937cfc..982c9610a 100644 --- a/src/flash/nor/pic32mx.c +++ b/src/flash/nor/pic32mx.c @@ -92,7 +92,7 @@ struct pic32mx_flash_bank { * DEVID values as per PIC32MX Flash Programming Specification Rev N */ -static const struct pic32mx_devs_s { +static const struct pic32mx_devs { uint32_t devid; const char *name; } pic32mx_devs[] = { diff --git a/src/jtag/commands.h b/src/jtag/commands.h index a1096daa7..825907733 100644 --- a/src/jtag/commands.h +++ b/src/jtag/commands.h @@ -15,7 +15,7 @@ #define OPENOCD_JTAG_COMMANDS_H /** - * The inferred type of a scan_command_s structure, indicating whether + * The inferred type of a scan_command structure, indicating whether * the command has the host scan in from the device, the host scan out * to the device, or both. */ @@ -29,7 +29,7 @@ enum scan_type { }; /** - * The scan_command provide a means of encapsulating a set of scan_field_s + * The scan_command provide a means of encapsulating a set of scan_field * structures that should be scanned in/out to the device. */ struct scan_command { @@ -123,7 +123,7 @@ union jtag_command_container { /** * The type of the @c jtag_command_container contained by a - * @c jtag_command_s structure. + * @c jtag_command structure. */ enum jtag_command_type { JTAG_SCAN = 1, diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c index f7c82efed..702b8fc6b 100644 --- a/src/target/xtensa/xtensa.c +++ b/src/target/xtensa/xtensa.c @@ -331,7 +331,7 @@ union xtensa_reg_val_u { uint8_t buf[4]; }; -static const struct xtensa_keyval_info_s xt_qerr[XT_QERR_NUM] = { +static const struct xtensa_keyval_info xt_qerr[XT_QERR_NUM] = { { .chrval = "E00", .intval = ERROR_FAIL }, { .chrval = "E01", .intval = ERROR_FAIL }, { .chrval = "E02", .intval = ERROR_COMMAND_ARGUMENT_INVALID }, diff --git a/src/target/xtensa/xtensa.h b/src/target/xtensa/xtensa.h index a220021a6..1d56f8368 100644 --- a/src/target/xtensa/xtensa.h +++ b/src/target/xtensa/xtensa.h @@ -97,7 +97,7 @@ enum xtensa_ar_scratch_set_e { XT_AR_SCRATCH_NUM }; -struct xtensa_keyval_info_s { +struct xtensa_keyval_info { char *chrval; int intval; }; @@ -283,7 +283,7 @@ struct xtensa { bool halt_request; uint32_t nx_stop_cause; uint32_t nx_reg_idx[XT_NX_REG_IDX_NUM]; - struct xtensa_keyval_info_s scratch_ars[XT_AR_SCRATCH_NUM]; + struct xtensa_keyval_info scratch_ars[XT_AR_SCRATCH_NUM]; bool regs_fetched; /* true after first register fetch completed successfully */ }; From ad87fbd1cf28760795c4e18f3318a2d720e5a8a6 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 11 Jun 2024 16:40:29 +0200 Subject: [PATCH 47/47] tcl/interface: support for Raspberry Pi 5 Make sure raspberrypi-native.cfg cannot be used on RPi5. Add raspberrypi5-gpiod.cfg which uses linuxgpiod adapter driver. Issue a warning if PCIe is in power save mode. While on it, re-format warnings issued from Tcl to look similar to LOG_WARNING() output. Change-Id: If19b0350bd5fff83d9a0c65999e33b161fb6957a Signed-off-by: Tomas Vanek Reviewed-on: https://review.openocd.org/c/openocd/+/8333 Tested-by: jenkins Reviewed-by: Jonathan Bell --- tcl/interface/raspberrypi-gpio-connector.cfg | 22 +++++++++------ tcl/interface/raspberrypi-native.cfg | 12 +++++--- tcl/interface/raspberrypi5-gpiod.cfg | 29 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 tcl/interface/raspberrypi5-gpiod.cfg diff --git a/tcl/interface/raspberrypi-gpio-connector.cfg b/tcl/interface/raspberrypi-gpio-connector.cfg index eff73fc92..af7266b51 100644 --- a/tcl/interface/raspberrypi-gpio-connector.cfg +++ b/tcl/interface/raspberrypi-gpio-connector.cfg @@ -10,6 +10,12 @@ # Do not forget the GND connection, e.g. pin 20 of the GPIO header. # +if { [info exists GPIO_CHIP] } { + set _GPIO_CHIP $GPIO_CHIP +} else { + set _GPIO_CHIP 0 +} + # GPIO 25 (pin 22) previously used for TMS/SWDIO is pulled-down by default. # The JTAG/SWD specification requires pull-up at the target board # for either signal. Connecting the signal pulled-up on the target @@ -19,23 +25,23 @@ echo "Warn : TMS/SWDIO moved to GPIO 8 (pin 24). Check the wiring please!" # Each of the JTAG lines need a gpio number set: tck tms tdi tdo # Header pin numbers: 23 24 19 21 -adapter gpio tck -chip 0 11 -adapter gpio tms -chip 0 8 -adapter gpio tdi -chip 0 10 -adapter gpio tdo -chip 0 9 +adapter gpio tck -chip $_GPIO_CHIP 11 +adapter gpio tms -chip $_GPIO_CHIP 8 +adapter gpio tdi -chip $_GPIO_CHIP 10 +adapter gpio tdo -chip $_GPIO_CHIP 9 # Each of the SWD lines need a gpio number set: swclk swdio # Header pin numbers: 23 24 -adapter gpio swclk -chip 0 11 -adapter gpio swdio -chip 0 8 +adapter gpio swclk -chip $_GPIO_CHIP 11 +adapter gpio swdio -chip $_GPIO_CHIP 8 # If you define trst or srst, use appropriate reset_config # Header pin numbers: TRST - 26, SRST - 18 -# adapter gpio trst -chip 0 7 +# adapter gpio trst -chip $_GPIO_CHIP 7 # reset_config trst_only -# adapter gpio srst -chip 0 24 +# adapter gpio srst -chip $_GPIO_CHIP 24 # reset_config srst_only srst_push_pull # or if you have both connected, diff --git a/tcl/interface/raspberrypi-native.cfg b/tcl/interface/raspberrypi-native.cfg index 7224723d6..c80f90a14 100644 --- a/tcl/interface/raspberrypi-native.cfg +++ b/tcl/interface/raspberrypi-native.cfg @@ -37,9 +37,9 @@ proc get_max_cpu_clock { default } { return $clock } - echo "WARNING: Host CPU clock unknown." - echo "WARNING: Using the highest possible value $default kHz as a safe default." - echo "WARNING: Expect JTAG/SWD clock significantly slower than requested." + echo "Warn : Host CPU clock unknown." + echo "Warn : Using the highest possible value $default kHz as a safe default." + echo "Warn : Expect JTAG/SWD clock significantly slower than requested." return $default } @@ -56,9 +56,13 @@ if {[string match *bcm2711* $compat]} { } elseif {[string match *bcm2835* $compat] || [string match *bcm2708* $compat]} { set clocks_per_timing_loop 6 set speed_offset 32 +} elseif {[string match *bcm2712* $compat]} { + echo "Error: Raspberrypi Pi 5 has moved GPIOs to PCIe connected RP1 chip." + echo "Error: Native GPIO handling is not supported, use 'raspberrypi5-gpiod.cfg'" + shutdown } else { set speed_offset 32 - echo "WARNING: Unknown type of the host SoC. Expect JTAG/SWD clock slower than requested." + echo "Warn : Unknown type of the host SoC. Expect JTAG/SWD clock slower than requested." } set clock [get_max_cpu_clock 2000000] diff --git a/tcl/interface/raspberrypi5-gpiod.cfg b/tcl/interface/raspberrypi5-gpiod.cfg new file mode 100644 index 000000000..f3fdde0f2 --- /dev/null +++ b/tcl/interface/raspberrypi5-gpiod.cfg @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Config for Raspberry Pi 5 used as a bitbang adapter. +# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html + +# Raspberry Pi 5 is not compatible with bcm2835gpio native GPIO driver. +# The linuxgpiod driver without configurable adapter speed runs at approximately +# 800 kHz (SWD writes) and 360 kHz (SWD reads) + +adapter driver linuxgpiod + +proc read_file { name } { + if {[catch {open $name r} fd]} { + return "" + } + set result [read $fd] + close $fd + return $result +} + +set pcie_aspm [read_file /sys/module/pcie_aspm/parameters/policy] +# escaping [ ] characters in string match pattern does not work in Jim-Tcl +if {![string match "**" [string map { "\[" < "\]" > } $pcie_aspm]]} { + echo "Warn : Switch PCIe power saving off or the first couple of pulses gets clocked as fast as 20 MHz" + echo "Warn : Issue 'echo performance | sudo tee /sys/module/pcie_aspm/parameters/policy'" +} + +set GPIO_CHIP 4 +source [find interface/raspberrypi-gpio-connector.cfg]