aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS14
-rw-r--r--Makefile.am2
-rwxr-xr-xbootstrap4
-rw-r--r--configure.ac10
-rw-r--r--contrib/60-openocd.rules21
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/openocd.121
-rw-r--r--doc/openocd.texi159
-rw-r--r--src/Makefile.am4
-rw-r--r--src/flash/nor/em357.c2
-rw-r--r--src/flash/nor/nrf5.c126
-rw-r--r--src/flash/nor/psoc6.c7
-rw-r--r--src/flash/nor/stm32l4x.c56
-rw-r--r--src/flash/nor/stm32l4x.h2
-rw-r--r--src/flash/startup.tcl6
-rw-r--r--src/helper/binarybuffer.c158
-rw-r--r--src/helper/binarybuffer.h17
-rw-r--r--src/helper/command.c40
-rw-r--r--src/helper/command.h11
-rw-r--r--src/helper/jep106.inc37
-rw-r--r--src/jtag/commands.c30
-rw-r--r--src/jtag/commands.h12
-rw-r--r--src/jtag/core.c106
-rw-r--r--src/jtag/drivers/amt_jtagaccel.c2
-rw-r--r--src/jtag/drivers/angie.c11
-rw-r--r--src/jtag/drivers/arm-jtag-ew.c20
-rw-r--r--src/jtag/drivers/bitbang.c21
-rw-r--r--src/jtag/drivers/bitq.c28
-rw-r--r--src/jtag/drivers/buspirate.c29
-rw-r--r--src/jtag/drivers/cmsis_dap.c20
-rw-r--r--src/jtag/drivers/driver.c8
-rw-r--r--src/jtag/drivers/ft232r.c18
-rw-r--r--src/jtag/drivers/ftdi.c25
-rw-r--r--src/jtag/drivers/gw16012.c7
-rw-r--r--src/jtag/drivers/jlink.c124
-rw-r--r--src/jtag/drivers/jtag_dpi.c10
-rw-r--r--src/jtag/drivers/jtag_vpi.c14
-rw-r--r--src/jtag/drivers/mpsse.c3
-rw-r--r--src/jtag/drivers/mpsse.h1
-rw-r--r--src/jtag/drivers/opendous.c20
-rw-r--r--src/jtag/drivers/openjtag.c10
-rw-r--r--src/jtag/drivers/osbdm.c12
-rw-r--r--src/jtag/drivers/rlink.c10
-rw-r--r--src/jtag/drivers/ulink.c11
-rw-r--r--src/jtag/drivers/usb_blaster/usb_blaster.c18
-rw-r--r--src/jtag/drivers/usbprog.c14
-rw-r--r--src/jtag/drivers/vdebug.c22
-rw-r--r--src/jtag/drivers/vsllink.c20
-rw-r--r--src/jtag/drivers/xds110.c12
-rw-r--r--src/jtag/drivers/xlnx-pcie-xvc.c11
-rw-r--r--src/jtag/hla/hla_interface.c23
-rw-r--r--src/jtag/jtag.h38
-rw-r--r--src/jtag/minidriver.h6
-rw-r--r--src/jtag/startup.tcl30
-rw-r--r--src/jtag/tcl.c21
-rw-r--r--src/rtos/hwthread.c53
-rw-r--r--src/server/gdb_server.c37
-rw-r--r--src/server/startup.tcl72
-rw-r--r--src/server/tcl_server.c21
-rw-r--r--src/server/telnet_server.c4
-rw-r--r--src/target/arm.h11
-rw-r--r--src/target/avrt.c26
-rw-r--r--src/target/cortex_m.c96
-rw-r--r--src/target/cortex_m.h43
-rw-r--r--src/target/esirisc.c2
-rw-r--r--src/target/esirisc_jtag.c5
-rw-r--r--src/target/lakemont.c4
-rw-r--r--src/target/riscv/asm.h6
-rw-r--r--src/target/riscv/batch.c11
-rw-r--r--src/target/riscv/batch.h32
-rw-r--r--src/target/riscv/debug_reg_printer.h5
-rw-r--r--src/target/riscv/field_helpers.h6
-rw-r--r--src/target/riscv/gdb_regs.h6
-rw-r--r--src/target/riscv/opcodes.h4
-rw-r--r--src/target/riscv/program.c4
-rw-r--r--src/target/riscv/program.h6
-rw-r--r--src/target/riscv/riscv-011.c46
-rw-r--r--src/target/riscv/riscv-011.h2
-rw-r--r--src/target/riscv/riscv-011_reg.c4
-rw-r--r--src/target/riscv/riscv-011_reg.h6
-rw-r--r--src/target/riscv/riscv-013.c549
-rw-r--r--src/target/riscv/riscv-013.h6
-rw-r--r--src/target/riscv/riscv-013_reg.c280
-rw-r--r--src/target/riscv/riscv-013_reg.h13
-rw-r--r--src/target/riscv/riscv.c282
-rw-r--r--src/target/riscv/riscv.h32
-rw-r--r--src/target/riscv/riscv_reg.c47
-rw-r--r--src/target/riscv/riscv_reg_impl.h16
-rw-r--r--src/target/target.c70
-rw-r--r--src/target/target.h3
-rw-r--r--src/target/target_request.c4
-rw-r--r--src/target/xtensa/xtensa.c8
-rw-r--r--src/target/xtensa/xtensa_chip.c2
-rw-r--r--src/transport/transport.c2
-rw-r--r--tcl/board/actux3.cfg2
-rw-r--r--tcl/board/at91sam9g20-ek.cfg4
-rw-r--r--tcl/board/mini2440.cfg2
-rw-r--r--tcl/board/mini6410.cfg2
-rw-r--r--tcl/board/netgear-wg102.cfg2
-rw-r--r--tcl/board/or1k_generic.cfg2
-rw-r--r--tcl/board/ti_am62a7_swd_native.cfg22
-rw-r--r--tcl/board/ti_am62p_swd_native.cfg22
-rw-r--r--tcl/board/ti_j722s_swd_native.cfg23
-rw-r--r--tcl/interface/nulink.cfg6
-rw-r--r--tcl/interface/raspberrypi5-gpiod.cfg3
-rw-r--r--tcl/interface/stlink.cfg6
-rw-r--r--tcl/interface/ti-icdi.cfg4
-rw-r--r--tcl/interface/vdebug.cfg4
-rw-r--r--tcl/target/allwinner_v3s.cfg2
-rw-r--r--tcl/target/ampere_emag.cfg2
-rw-r--r--tcl/target/bl702.cfg60
-rw-r--r--tcl/target/esi32xx.cfg2
-rw-r--r--tcl/target/esp_common.cfg2
-rw-r--r--tcl/target/icepick.cfg2
-rw-r--r--tcl/target/omap4430.cfg2
-rw-r--r--tcl/target/omap4460.cfg2
-rw-r--r--tcl/target/omapl138.cfg2
-rw-r--r--tcl/target/psoc6.cfg4
-rw-r--r--tcl/target/rp2040.cfg2
-rw-r--r--tcl/target/ti_k3.cfg10
-rw-r--r--tcl/target/u8500.cfg6
-rw-r--r--tcl/target/xtensa.cfg2
-rwxr-xr-xtools/scripts/checkpatch.pl4
-rw-r--r--uncrustify.cfg2
124 files changed, 2065 insertions, 1437 deletions
diff --git a/AUTHORS b/AUTHORS
index 2a989f3..7489834 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,12 +1,2 @@
-Dominic Rath <Dominic.Rath@gmx.de>
-Magnus Lundin <lundin@mlu.mine.nu>
-Michael Fischer <fischermi@t-online.de>
-Spencer Oliver <spen@spen-soft.co.uk>
-Carsten Schlote <schlote@vahanus.net>
-Øyvind Harboe <oyvind.harboe@zylin.com>
-Duane Ellis <openocd@duaneellis.com>
-Michael Schwingen <michael@schwingen.org>
-Rick Altherr <kc8apf@users.berlios.de>
-David Brownell <dbrownell@users.sourceforge.net>
-Vincint Palatin <vpalatin@users.berlios.de>
-Zachary T Welch <zw@superlucidity.net>
+Please check the source code files and/or Git history for a list of all authors
+and contributors.
diff --git a/Makefile.am b/Makefile.am
index f9e0d6b..0f24ee6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,8 @@ AM_CPPFLAGS = $(HOST_CPPFLAGS)\
if INTERNAL_JIMTCL
AM_CPPFLAGS += -I$(top_srcdir)/jimtcl \
-I$(top_builddir)/jimtcl
+else
+AM_CPPFLAGS += $(JIMTCL_CFLAGS)
endif
EXTRA_DIST += \
BUGS \
diff --git a/bootstrap b/bootstrap
index cf6167f..7d4ca37 100755
--- a/bootstrap
+++ b/bootstrap
@@ -38,8 +38,8 @@ if [ -n "$SKIP_SUBMODULE" ]; then
echo "Skipping submodule setup"
else
echo "Setting up submodules"
- git submodule init
- git submodule update
+ git submodule sync
+ git submodule update --init
fi
if [ -x src/jtag/drivers/libjaylink/autogen.sh ]; then
diff --git a/configure.ac b/configure.ac
index c6e02b6..f13727e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -595,6 +595,15 @@ AS_IF([test "x$use_internal_jimtcl" = "xyes"], [
], [
AC_MSG_ERROR([jimtcl not found, run git submodule init and git submodule update.])
])
+], [
+ PKG_CHECK_MODULES([JIMTCL], [jimtcl >= 0.79], [
+ have_jimtcl_pkg_config=yes
+ ], [
+ have_jimtcl_pkg_config=no
+ AC_CHECK_HEADER([jim.h], [], [
+ AC_MSG_ERROR([jimtcl is required but not found via pkg-config and system includes])
+ ])
+ ])
])
AS_IF([test "x$build_remote_bitbang" = "xyes"], [
@@ -782,6 +791,7 @@ AM_CONDITIONAL([DMEM], [test "x$build_dmem" = "xyes"])
AM_CONDITIONAL([HAVE_CAPSTONE], [test "x$enable_capstone" != "xno"])
AM_CONDITIONAL([INTERNAL_JIMTCL], [test "x$use_internal_jimtcl" = "xyes"])
+AM_CONDITIONAL([HAVE_JIMTCL_PKG_CONFIG], [test "x$have_jimtcl_pkg_config" = "xyes"])
AM_CONDITIONAL([INTERNAL_LIBJAYLINK], [test "x$use_internal_libjaylink" = "xyes"])
# Look for environ alternatives. Possibility #1: is environ in unistd.h or stdlib.h?
diff --git a/contrib/60-openocd.rules b/contrib/60-openocd.rules
index fe8b00c..29f8d7a 100644
--- a/contrib/60-openocd.rules
+++ b/contrib/60-openocd.rules
@@ -29,6 +29,27 @@ ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="660", GROUP="plugdev",
# Original FT231XQ VID:PID
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", MODE="660", GROUP="plugdev", TAG+="uaccess"
+# Original FT2233HP VID:PID
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6040", MODE="660", GROUP="plugdev", TAG+="uaccess"
+
+# Original FT4233HP VID:PID
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6041", MODE="660", GROUP="plugdev", TAG+="uaccess"
+
+# Original FT2232HP VID:PID
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6042", MODE="660", GROUP="plugdev", TAG+="uaccess"
+
+# Original FT4232HP VID:PID
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6043", MODE="660", GROUP="plugdev", TAG+="uaccess"
+
+# Original FT233HP VID:PID
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6044", MODE="660", GROUP="plugdev", TAG+="uaccess"
+
+# Original FT232HP VID:PID
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6045", MODE="660", GROUP="plugdev", TAG+="uaccess"
+
+# Original FT4232HA VID:PID
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6048", MODE="660", GROUP="plugdev", TAG+="uaccess"
+
# DISTORTEC JTAG-lock-pick Tiny 2
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8220", MODE="660", GROUP="plugdev", TAG+="uaccess"
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 6759203..17d051f 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
info_TEXINFOS += %D%/openocd.texi
%C%_openocd_TEXINFOS = %D%/fdl.texi
diff --git a/doc/openocd.1 b/doc/openocd.1
index 4278486..34ec761 100644
--- a/doc/openocd.1
+++ b/doc/openocd.1
@@ -1,24 +1,21 @@
-.TH "OPENOCD" "1" "November 24, 2009"
+.TH "OPENOCD" "1" "June 18, 2024"
.SH "NAME"
openocd \- A free and open on\-chip debugging, in\-system programming and
-boundary\-scan testing tool for ARM and MIPS systems
+boundary\-scan testing tool for microcontrollers and other embedded devices
.SH "SYNOPSIS"
-.B openocd \fR[\fB\-fsdlcphv\fR] [\fB\-\-file\fR <filename>] [\fB\-\-search\fR <dirname>] [\fB\-\-debug\fR <debuglevel>] [\fB\-\-log_output\fR <filename>] [\fB\-\-command\fR <cmd>] [\fB\-\-pipe\fR] [\fB\-\-help\fR] [\fB\-\-version\fR]
+.B openocd \fR[\fB\-fsdlchv\fR] [\fB\-\-file\fR <filename>] [\fB\-\-search\fR <dirname>] [\fB\-\-debug\fR <debuglevel>] [\fB\-\-log_output\fR <filename>] [\fB\-\-command\fR <cmd>] [\fB\-\-help\fR] [\fB\-\-version\fR]
.SH "DESCRIPTION"
.B OpenOCD
is an on\-chip debugging, in\-system programming and boundary\-scan
-testing tool for various ARM and MIPS systems.
+testing tool for various microcontrollers and other embedded devices.
.PP
-The debugger uses an IEEE 1149\-1 compliant JTAG TAP bus master to access
-on\-chip debug functionality available on ARM based microcontrollers or
-system-on-chip solutions. For MIPS systems the EJTAG interface is supported.
+Various different types of debug adapters as well as transport protocols like
+JTAG and SWD are supported by OpenOCD, please check the \fIopenocd\fR info page
+for the complete list.
.PP
User interaction is realized through a telnet command line interface,
a gdb (the GNU debugger) remote protocol server, and a simplified RPC
connection that can be used to interface with OpenOCD's Jim Tcl engine.
-.PP
-OpenOCD supports various different types of JTAG interfaces/programmers,
-please check the \fIopenocd\fR info page for the complete list.
.SH "OPTIONS"
.TP
.B "\-f, \-\-file <filename>"
@@ -68,8 +65,6 @@ Note that you will need to explicitly invoke
.I init
if the command requires access to a target or flash.
.TP
-.B "\-p, \-\-pipe"
-Use pipes when talking to gdb.
.TP
.B "\-h, \-\-help"
Show a help text and exit.
@@ -82,8 +77,6 @@ Please report any bugs on the mailing list at
.SH "LICENCE"
.B OpenOCD
is covered by the GNU General Public License (GPL), version 2 or later.
-.SH "SEE ALSO"
-.BR jtag (1)
.PP
The full documentation for
.B openocd
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 5bd4e89..ec862bd 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -930,8 +930,8 @@ a board with an Atmel AT91SAM7X256 microcontroller:
source [find interface/ftdi/signalyzer.cfg]
# GDB can also flash my flash!
-gdb_memory_map enable
-gdb_flash_program enable
+gdb memory_map enable
+gdb flash_program enable
source [find target/sam7x256.cfg]
@end example
@@ -940,8 +940,8 @@ Here is the command line equivalent of that configuration:
@example
openocd -f interface/ftdi/signalyzer.cfg \
- -c "gdb_memory_map enable" \
- -c "gdb_flash_program enable" \
+ -c "gdb memory_map enable" \
+ -c "gdb flash_program enable" \
-f target/sam7x256.cfg
@end example
@@ -2179,18 +2179,16 @@ only during configuration (before those ports are opened).
For reasons including security, you may wish to prevent remote
access using one or more of these ports.
In such cases, just specify the relevant port number as "disabled".
-If you disable all access through TCP/IP, you will need to
-use the command line @option{-pipe} option.
You can request the operating system to select one of the available
ports for the server by specifying the relevant port number as "0".
-@anchor{gdb_port}
-@deffn {Config Command} {gdb_port} [number]
+@anchor{gdb port}
+@deffn {Config Command} {gdb port} [number]
@cindex GDB server
Normally gdb listens to a TCP/IP port, but GDB can also
communicate via pipes(stdin/out or named pipes). The name
-"gdb_port" stuck because it covers probably more than 90% of
+"gdb port" stuck because it covers probably more than 90% of
the normal use cases.
No arguments reports GDB port. "pipe" means listen to stdin
@@ -2205,7 +2203,7 @@ Output pipe is the same name as input pipe, but with 'o' appended,
e.g. /var/gdb, /var/gdbo.
The GDB port for the first target will be the base port, the
-second target will listen on gdb_port + 1, and so on.
+second target will listen on port + 1, and so on.
When not specified during the configuration stage,
the port @var{number} defaults to 3333.
When @var{number} is not a numeric value, incrementing it to compute
@@ -2214,12 +2212,12 @@ the next port number does not work. In this case, specify the proper
commands @command{target create} or @command{$target_name configure}.
@xref{gdbportoverride,,option -gdb-port}.
-Note: when using "gdb_port pipe", increasing the default remote timeout in
+Note: when using "gdb port pipe", increasing the default remote timeout in
gdb (with 'set remotetimeout') is recommended. An insufficient timeout may
cause initialization to fail with "Unknown remote qXfer reply: OK".
@end deffn
-@deffn {Config Command} {tcl_port} [number]
+@deffn {Config Command} {tcl port} [number]
Specify or query the port used for a simplified RPC
connection that can be used by clients to issue TCL commands and get the
output from the Tcl engine.
@@ -2248,7 +2246,7 @@ The ones listed here are static and global.
@xref{targetevents,,Target Events}, about configuring target-specific event handling.
@anchor{gdbbreakpointoverride}
-@deffn {Command} {gdb_breakpoint_override} [@option{hard}|@option{soft}|@option{disable}]
+@deffn {Command} {gdb breakpoint_override} [@option{hard}|@option{soft}|@option{disable}]
Force breakpoint type for gdb @command{break} commands.
This option supports GDB GUIs which don't
distinguish hard versus soft breakpoints, if the default OpenOCD and
@@ -2257,41 +2255,41 @@ breakpoints if the memory map has been set up for flash regions.
@end deffn
@anchor{gdbflashprogram}
-@deffn {Config Command} {gdb_flash_program} (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb flash_program} (@option{enable}|@option{disable})
Set to @option{enable} to cause OpenOCD to program the flash memory when a
vFlash packet is received.
The default behaviour is @option{enable}.
@end deffn
-@deffn {Config Command} {gdb_memory_map} (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb memory_map} (@option{enable}|@option{disable})
Set to @option{enable} to cause OpenOCD to send the memory configuration to GDB when
requested. GDB will then know when to set hardware breakpoints, and program flash
-using the GDB load command. @command{gdb_flash_program enable} must also be enabled
+using the GDB load command. @command{gdb flash_program enable} must also be enabled
for flash programming to work.
Default behaviour is @option{enable}.
-@xref{gdbflashprogram,,gdb_flash_program}.
+@xref{gdbflashprogram,,gdb flash_program}.
@end deffn
-@deffn {Config Command} {gdb_report_data_abort} (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb report_data_abort} (@option{enable}|@option{disable})
Specifies whether data aborts cause an error to be reported
by GDB memory read packets.
The default behaviour is @option{disable};
use @option{enable} see these errors reported.
@end deffn
-@deffn {Config Command} {gdb_report_register_access_error} (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb report_register_access_error} (@option{enable}|@option{disable})
Specifies whether register accesses requested by GDB register read/write
packets report errors or not.
The default behaviour is @option{disable};
use @option{enable} see these errors reported.
@end deffn
-@deffn {Config Command} {gdb_target_description} (@option{enable}|@option{disable})
+@deffn {Config Command} {gdb target_description} (@option{enable}|@option{disable})
Set to @option{enable} to cause OpenOCD to send the target descriptions to gdb via qXfer:features:read packet.
The default behaviour is @option{enable}.
@end deffn
-@deffn {Command} {gdb_save_tdesc}
+@deffn {Command} {gdb save_tdesc}
Saves the target description file to the local file system.
The file name is @i{target_name}.xml.
@@ -2989,6 +2987,11 @@ Display free device internal memory.
Set the JTAG command version to be used. Without argument, show the actual JTAG
command version.
@end deffn
+@deffn {Command} {jlink targetpower} [@option{0}|@option{1}|@option{on}|@option{off}]
+Switch the 5@ V target power supply on or off.
+Without argument, show the state of the target power supply.
+The target power supply is usually connected to pin 19 of the 20-pin connector.
+@end deffn
@deffn {Command} {jlink config}
Display the device configuration.
@end deffn
@@ -3228,19 +3231,19 @@ versions of firmware where serial number is reset after first use. Suggest
using ST firmware update utility to upgrade ST-LINK firmware even if current
version reported is V2.J21.S4.
-@deffn {Config Command} {hla_device_desc} description
+@deffn {Config Command} {hla device_desc} description
Currently Not Supported.
@end deffn
-@deffn {Config Command} {hla_layout} (@option{stlink}|@option{icdi}|@option{nulink})
+@deffn {Config Command} {hla layout} (@option{stlink}|@option{icdi}|@option{nulink})
Specifies the adapter layout to use.
@end deffn
-@deffn {Config Command} {hla_vid_pid} [vid pid]+
+@deffn {Config Command} {hla vid_pid} [vid pid]+
Pairs of vendor IDs and product IDs of the device.
@end deffn
-@deffn {Config Command} {hla_stlink_backend} (usb | tcp [port])
+@deffn {Config Command} {hla stlink_backend} (usb | tcp [port])
@emph{ST-Link only:} Choose between 'exclusive' USB communication (the default backend) or
'shared' mode using ST-Link TCP server (the default port is 7184).
@@ -3249,7 +3252,7 @@ available from @url{https://www.st.com/en/development-tools/st-link-server.html,
ST-LINK server software module}.
@end deffn
-@deffn {Command} {hla_command} command
+@deffn {Command} {hla command} command
Execute a custom adapter-specific command. The @var{command} string is
passed as is to the underlying adapter layout handler.
@end deffn
@@ -3719,20 +3722,18 @@ displays the names of the transports supported by this
version of OpenOCD.
@end deffn
-@deffn {Command} {transport select} @option{transport_name}
+@deffn {Command} {transport select} [transport_name]
Select which of the supported transports to use in this OpenOCD session.
When invoked with @option{transport_name}, attempts to select the named
-transport. The transport must be supported by the debug adapter
+transport. The transport must be supported by the debug adapter
hardware and by the version of OpenOCD you are using (including the
adapter's driver).
-
-If no transport has been selected and no @option{transport_name} is
-provided, @command{transport select} auto-selects the first transport
-supported by the debug adapter.
-
-@command{transport select} always returns the name of the session's selected
-transport, if any.
+When invoked with no transport name:
+@itemize @minus
+@item if no transport has been selected yet, it auto-selects the first transport supported by the debug adapter
+@item it returns the name of the session's selected transport
+@end itemize
@end deffn
@subsection JTAG Transport
@@ -5190,6 +5191,38 @@ On ADIv6 DAP @var{ap_number} is the base address of the DAP AP the target is con
Use this option with systems where multiple, independent cores are connected
to separate access ports of the same DAP.
+@item @code{-dbgbase} @var{dbg_base_address} -- set the base address of the
+debug controller.
+This is ignored and not required for target types that have the debug controller
+at fixed addresses, like @code{cortex_m}.
+On DAP based SoC, OpenOCD can parse the ROM table in the DAP access port to
+identify the base address of the debug controller, but the parsing can be slow
+on devices with big ROM tables.
+While using @code{-dbgbase} is suggested to speed up the target examination,
+it is often the only viable solution for devices with incorrect ROM table
+content or with ROM table partially not accessible due to clock gating or
+power management.
+
+@item @code{-coreid} @var{coreid} -- set an index to identify the CPU or its
+debug controller.
+
+@itemize @minus
+@item When @code{-dbgbase} option is not provided on devices with multiple
+CPUs on the same DAP access port
+(e.g. @code{cortex_a}, @code{cortex_r4}, @code{aarch64} and @code{armv8r}),
+this option specifies that the ROM table parsing should select the CPU in
+position @var{coreid}.
+
+@item On target type @code{riscv}, @var{coreid} specifies the hart
+(HARdware Threads) on the DM (Debug Module). It is used on multi-hart
+devices to index a specific hart ID.
+When not present, it's default value is zero.
+
+@item This value @var{coreid} is currently also used in other contexts as a
+general CPU index, e.g. in SMP nodes or to select a specific CPU in a chip.
+To avoid confusion, these additional use cases are going to be dropped.
+@end itemize
+
@item @code{-cti} @var{cti_name} -- set Cross-Trigger Interface (CTI) connected
to the target. Currently, only the @code{aarch64} target makes use of this option,
where it is a mandatory configuration for the target run control.
@@ -5197,11 +5230,11 @@ where it is a mandatory configuration for the target run control.
for instruction on how to declare and control a CTI instance.
@anchor{gdbportoverride}
-@item @code{-gdb-port} @var{number} -- see command @command{gdb_port} for the
+@item @code{-gdb-port} @var{number} -- @xref{gdb port,,command gdb port}, for the
possible values of the parameter @var{number}, which are not only numeric values.
Use this option to override, for this target only, the global parameter set with
-command @command{gdb_port}.
-@xref{gdb_port,,command gdb_port}.
+command @command{gdb port}.
+@xref{gdb port,,command gdb port}.
@item @code{-gdb-max-connections} @var{number} -- EXPERIMENTAL: set the maximum
number of GDB connections that are allowed for the target. Default is 1.
@@ -10587,7 +10620,7 @@ the destination of the trace data:
@item @option{external} -- configure TPIU/SWO to let user capture trace
output externally, either with an additional UART or with a logic analyzer (default);
@item @option{-} -- configure TPIU/SWO and debug adapter to gather trace data
-and forward it to @command{tcl_trace} command;
+and forward it to @command{tcl trace} command;
@item @option{:}@var{port} -- configure TPIU/SWO and debug adapter to gather
trace data, open a TCP server at port @var{port} and send the trace data to
each connected client;
@@ -11354,10 +11387,15 @@ 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
+@deffn {Command} {riscv use_bscan_tunnel} width [type]
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.
+@var{width} of the DM transport TAP's instruction register to enable. The
+@var{width} should fit into 7 bits. Supply a value of 0 to disable.
+Pass a second argument (optional) to indicate Bscan Tunnel Type:
+@enumerate
+@item 0:(default) NESTED_TAP
+@item 1: DATA_REGISTER
+@end enumerate
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
@@ -11524,6 +11562,21 @@ as in the mie CSR (defined in the RISC-V Privileged Spec).
For details on this trigger type, see the RISC-V Debug Specification.
@end deffn
+@deffn {Command} {riscv reserve_trigger} [index @option{on|off}]
+Manages the set of reserved triggers. Reserving a trigger results in OpenOCD
+not using it internally (e.g. skipping it when setting a watchpoint or a
+hardware breakpoint), so that the user or the application has unfettered
+control over the trigger. By default there are no reserved triggers.
+
+@enumerate
+@item @var{index} specifies the index of a trigger to reserve or free up.
+@item The second argument specifies whether the trigger should be reserved
+(@var{on}) or a prior reservation cancelled (@var{off}).
+@item If called without parameters, returns indices of reserved triggers.
+@end enumerate
+
+@end deffn
+
@deffn {Command} {riscv itrigger clear}
Clear the type 4 trigger that was set using @command{riscv itrigger set}.
@end deffn
@@ -12593,7 +12646,7 @@ target remote localhost:3333
A pipe connection is typically started as follows:
@example
target extended-remote | \
- openocd -c "gdb_port pipe; log_output openocd.log"
+ openocd -c "gdb port pipe; log_output openocd.log"
@end example
This would cause GDB to run OpenOCD and communicate using pipes (stdin/stdout).
Using this method has the advantage of GDB starting/stopping OpenOCD for the debug
@@ -12677,7 +12730,7 @@ using @command{gdb -x filename}.
By default the target memory map is sent to GDB. This can be disabled by
the following OpenOCD configuration option:
@example
-gdb_memory_map disable
+gdb memory_map disable
@end example
For this to function correctly a valid flash configuration must also be set
in OpenOCD. For faster performance you should also configure a valid
@@ -12685,8 +12738,8 @@ working area.
Informing GDB of the memory map of the target will enable GDB to protect any
flash areas of the target and use hardware breakpoints by default. This means
-that the OpenOCD option @command{gdb_breakpoint_override} is not required when
-using a memory map. @xref{gdbbreakpointoverride,,gdb_breakpoint_override}.
+that the OpenOCD option @command{gdb breakpoint_override} is not required when
+using a memory map. @xref{gdbbreakpointoverride,,gdb breakpoint_override}.
To view the configured memory map in GDB, use the GDB command @option{info mem}.
All other unassigned addresses within GDB are treated as RAM.
@@ -12697,7 +12750,7 @@ This can be changed to the old behaviour by using the following GDB command
set mem inaccessible-by-default off
@end example
-If @command{gdb_flash_program enable} is also used, GDB will be able to
+If @command{gdb flash_program enable} is also used, GDB will be able to
program any flash memory using the vFlash interface.
GDB will look at the target memory map when a load command is given, if any
@@ -12736,9 +12789,9 @@ $_TARGETNAME configure -event gdb-attach @{@}
@end example
If any of installed flash banks does not support probe on running target,
-switch off gdb_memory_map:
+switch off gdb memory_map:
@example
-gdb_memory_map disable
+gdb memory_map disable
@end example
Ensure GDB is configured without interrupt-on-connect.
@@ -12747,7 +12800,7 @@ Some GDB versions set it by default, some does not.
set remote interrupt-on-connect off
@end example
-If you switched gdb_memory_map off, you may want to setup GDB memory map
+If you switched gdb memory_map off, you may want to setup GDB memory map
manually or issue @command{set mem inaccessible-by-default off}
Now you can issue GDB command @command{target extended-remote ...} and inspect memory
@@ -12960,7 +13013,7 @@ OpenOCD provides a simple RPC server that allows to run arbitrary Tcl
commands and receive the results.
To access it, your application needs to connect to a configured TCP port
-(see @command{tcl_port}). Then it can pass any string to the
+(see @command{tcl port}). Then it can pass any string to the
interpreter terminating it with @code{0x1a} and wait for the return
value (it will be terminated with @code{0x1a} as well). This can be
repeated as many times as desired without reopening the connection.
@@ -12986,7 +13039,7 @@ type target_state state [state-name]
type target_reset mode [reset-mode]
@end verbatim
-@deffn {Command} {tcl_notifications} [on/off]
+@deffn {Command} {tcl notifications} [on/off]
Toggle output of target notifications to the current Tcl RPC server.
Only available from the Tcl RPC server.
Defaults to off.
@@ -13005,7 +13058,7 @@ Target trace data is emitted as a Tcl associative array in the following format.
type target_trace data [trace-data-hex-encoded]
@end verbatim
-@deffn {Command} {tcl_trace} [on/off]
+@deffn {Command} {tcl trace} [on/off]
Toggle output of target trace data to the current Tcl RPC server.
Only available from the Tcl RPC server.
Defaults to off.
diff --git a/src/Makefile.am b/src/Makefile.am
index 6d79cd6..4d1c1a2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,8 +17,12 @@ bin_PROGRAMS += %D%/openocd
if INTERNAL_JIMTCL
%C%_openocd_LDADD += $(top_builddir)/jimtcl/libjim.a
else
+if HAVE_JIMTCL_PKG_CONFIG
+%C%_openocd_LDADD += $(JIMTCL_LIBS)
+else
%C%_openocd_LDADD += -ljim
endif
+endif
%C%_libopenocd_la_CPPFLAGS =
diff --git a/src/flash/nor/em357.c b/src/flash/nor/em357.c
index 043494c..207346f 100644
--- a/src/flash/nor/em357.c
+++ b/src/flash/nor/em357.c
@@ -709,7 +709,7 @@ static int em357_probe(struct flash_bank *bank)
em357_info->ppage_size = 4;
- LOG_INFO("flash size = %d KiB", num_pages*page_size/1024);
+ LOG_INFO("flash size = %d KiB", num_pages * page_size / 1024);
free(bank->sectors);
diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c
index f07433e..5cb552a 100644
--- a/src/flash/nor/nrf5.c
+++ b/src/flash/nor/nrf5.c
@@ -117,20 +117,24 @@ struct nrf5_map {
struct nrf5_info {
unsigned int refcount;
+ bool chip_probed;
struct nrf5_bank {
struct nrf5_info *chip;
bool probed;
} bank[2];
+
struct target *target;
- /* chip identification stored in nrf5_probe() for use in nrf5_info() */
+ /* chip identification stored in nrf5_probe_chip()
+ * for use in nrf5_info() and nrf5_setup_bank() */
bool ficr_info_valid;
struct nrf52_ficr_info ficr_info;
const struct nrf5_device_spec *spec;
uint16_t hwid;
enum nrf5_features features;
- unsigned int flash_size_kb;
+ uint32_t flash_page_size;
+ uint32_t flash_num_sectors;
unsigned int ram_size_kb;
const struct nrf5_map *map;
@@ -341,16 +345,19 @@ const struct flash_driver nrf5_flash, nrf51_flash;
static bool nrf5_bank_is_probed(const struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
-
return nbank->probed;
}
-static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank)
+static bool nrf5_chip_is_probed(const struct flash_bank *bank)
{
+ struct nrf5_bank *nbank = bank->driver_priv;
struct nrf5_info *chip = nbank->chip;
- assert(chip);
+ return chip->chip_probed;
+}
+static bool nrf5_bank_is_uicr(const struct nrf5_bank *nbank)
+{
+ struct nrf5_info *chip = nbank->chip;
return nbank == &chip->bank[1];
}
@@ -470,9 +477,7 @@ static int nrf51_protect_check_clenr0(struct flash_bank *bank)
uint32_t clenr0;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
res = target_read_u32(chip->target, NRF51_FICR_CLENR0,
&clenr0);
@@ -501,9 +506,7 @@ static int nrf51_protect_check_clenr0(struct flash_bank *bank)
static int nrf52_protect_check_bprot(struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
static uint32_t nrf5_bprot_offsets[4] = { 0x600, 0x604, 0x610, 0x614 };
uint32_t bprot_reg = 0;
@@ -528,9 +531,7 @@ static int nrf52_protect_check_bprot(struct flash_bank *bank)
static int nrf5_protect_check(struct flash_bank *bank)
{
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))
@@ -554,9 +555,7 @@ static int nrf51_protect_clenr0(struct flash_bank *bank, int set, unsigned int f
uint32_t clenr0, ppfc;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
if (first != 0) {
LOG_ERROR("Code region 0 must start at the beginning of the bank");
@@ -614,9 +613,7 @@ 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 (nrf5_bank_is_uicr(nbank)) {
@@ -701,16 +698,15 @@ static int nrf5_get_chip_type_str(const struct nrf5_info *chip, char *buf, unsig
static int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
char chip_type_str[256];
if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
return ERROR_FAIL;
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
command_print_sameline(cmd, "%s %ukB Flash, %ukB RAM",
- chip_type_str, chip->flash_size_kb, chip->ram_size_kb);
+ chip_type_str, flash_size_kb, chip->ram_size_kb);
return ERROR_OK;
}
@@ -838,14 +834,12 @@ static int nrf51_get_ram_size(struct target *target, uint32_t *ram_size)
return res;
}
-static int nrf5_probe(struct flash_bank *bank)
+static int nrf5_probe_chip(struct flash_bank *bank)
{
int res = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
struct target *target = chip->target;
chip->spec = NULL;
@@ -968,9 +962,8 @@ static int nrf5_probe(struct flash_bank *bank)
}
/* 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, ficr_base + ficr_offsets->codepagesize,
- &flash_page_size);
+ &chip->flash_page_size);
if (res != ERROR_OK) {
LOG_ERROR("Couldn't read code page size");
return res;
@@ -978,69 +971,93 @@ static int nrf5_probe(struct flash_bank *bank)
/* Note the register name is misleading,
* 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, ficr_base + ficr_offsets->codesize,
- &num_sectors);
+ &chip->flash_num_sectors);
if (res != ERROR_OK) {
LOG_ERROR("Couldn't read code memory size");
return res;
}
- chip->flash_size_kb = num_sectors * flash_page_size / 1024;
+ char chip_type_str[256];
+ if (nrf5_get_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)
+ return ERROR_FAIL;
- if (!chip->bank[0].probed && !chip->bank[1].probed) {
- char chip_type_str[256];
- 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",
- device_is_unknown ? "Unknown device: " : "",
- chip_type_str,
- chip->flash_size_kb,
- chip->ram_size_kb);
- }
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
+ const bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid);
+ LOG_INFO("%s%s %ukB Flash, %ukB RAM",
+ device_is_unknown ? "Unknown device: " : "",
+ chip_type_str,
+ flash_size_kb,
+ chip->ram_size_kb);
- free(bank->sectors);
+ chip->chip_probed = true;
+ return ERROR_OK;
+}
+
+static int nrf5_setup_bank(struct flash_bank *bank)
+{
+ struct nrf5_bank *nbank = bank->driver_priv;
+ struct nrf5_info *chip = nbank->chip;
if (bank->base == chip->map->flash_base) {
+ unsigned int flash_size_kb = chip->flash_num_sectors * chip->flash_page_size / 1024;
/* Sanity check */
- if (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb)
+ if (chip->spec && flash_size_kb != chip->spec->flash_size_kb)
LOG_WARNING("Chip's reported Flash capacity does not match expected one");
- if (chip->ficr_info_valid && chip->flash_size_kb != chip->ficr_info.flash)
+ if (chip->ficr_info_valid && flash_size_kb != chip->ficr_info.flash)
LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH");
- bank->num_sectors = num_sectors;
- bank->size = num_sectors * flash_page_size;
+ bank->num_sectors = chip->flash_num_sectors;
+ bank->size = chip->flash_num_sectors * chip->flash_page_size;
- bank->sectors = alloc_block_array(0, flash_page_size, num_sectors);
+ bank->sectors = alloc_block_array(0, chip->flash_page_size, bank->num_sectors);
if (!bank->sectors)
return ERROR_FAIL;
chip->bank[0].probed = true;
- } else {
+ } else if (bank->base == chip->map->uicr_base) {
/* UICR bank */
bank->num_sectors = 1;
- bank->size = flash_page_size;
+ bank->size = chip->flash_page_size;
- bank->sectors = alloc_block_array(0, flash_page_size, num_sectors);
+ bank->sectors = alloc_block_array(0, chip->flash_page_size, bank->num_sectors);
if (!bank->sectors)
return ERROR_FAIL;
bank->sectors[0].is_protected = 0;
chip->bank[1].probed = true;
+ } else {
+ LOG_ERROR("Invalid nRF bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FLASH_BANK_INVALID;
}
return ERROR_OK;
}
+static int nrf5_probe(struct flash_bank *bank)
+{
+ /* probe always reads actual info from the device */
+ int res = nrf5_probe_chip(bank);
+ if (res != ERROR_OK)
+ return res;
+
+ return nrf5_setup_bank(bank);
+}
+
static int nrf5_auto_probe(struct flash_bank *bank)
{
if (nrf5_bank_is_probed(bank))
return ERROR_OK;
- return nrf5_probe(bank);
+ if (!nrf5_chip_is_probed(bank)) {
+ int res = nrf5_probe_chip(bank);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ return nrf5_setup_bank(bank);
}
@@ -1214,9 +1231,7 @@ static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer,
}
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
assert(offset % 4 == 0);
assert(count % 4 == 0);
@@ -1276,9 +1291,7 @@ static int nrf5_erase(struct flash_bank *bank, unsigned int first,
}
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
- assert(chip);
/* UICR CLENR0 based protection used on nRF51 prevents erase
* absolutely silently. NVMC has no flag to indicate the protection
@@ -1322,7 +1335,6 @@ error:
static void nrf5_free_driver_priv(struct flash_bank *bank)
{
struct nrf5_bank *nbank = bank->driver_priv;
- assert(nbank);
struct nrf5_info *chip = nbank->chip;
if (!chip)
return;
@@ -1372,8 +1384,8 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command)
case NRF53NET_UICR_BASE:
break;
default:
- LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
- return ERROR_FAIL;
+ LOG_ERROR("Invalid nRF bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FLASH_BANK_INVALID;
}
chip = nrf5_get_chip(bank->target);
@@ -1418,17 +1430,13 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command)
if (res != ERROR_OK)
return res;
- assert(bank);
-
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
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) {
uint32_t ppfc;
diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c
index 859b3e9..47f3ac6 100644
--- a/src/flash/nor/psoc6.c
+++ b/src/flash/nor/psoc6.c
@@ -223,6 +223,8 @@ static int ipc_poll_lock_stat(struct target *target, uint32_t ipc_id, bool lock_
{
int hr;
uint32_t reg_val;
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ bool is_cm0 = (armv7m->arm.arch == ARM_ARCH_V6M);
struct timeout to;
timeout_init(&to, IPC_TIMEOUT_MS);
@@ -244,7 +246,7 @@ static int ipc_poll_lock_stat(struct target *target, uint32_t ipc_id, bool lock_
return ERROR_OK;
}
- if (target->coreid) {
+ if (!is_cm0) {
LOG_WARNING("SROM API calls via CM4 target are supported on single-core PSoC6 devices only. "
"Please perform all Flash-related operations via CM0+ target on dual-core devices.");
}
@@ -886,7 +888,8 @@ static int handle_reset_halt(struct target *target)
{
int hr;
uint32_t reset_addr;
- bool is_cm0 = (target->coreid == 0);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ bool is_cm0 = (armv7m->arm.arch == ARM_ARCH_V6M);
/* Halt target device */
if (target->state != TARGET_HALTED) {
diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index 0399385..bb6e9ef 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -120,6 +120,12 @@
* http://www.st.com/resource/en/reference_manual/dm00346336.pdf
*/
+/* STM32U5xxx series for reference.
+ *
+ * RM0456 (STM32U5xx)
+ * http://www.st.com/resource/en/reference_manual/dm00477635.pdf
+ */
+
/* Erase time can be as high as 25ms, 10x this and assume it's toast... */
#define FLASH_ERASE_TIMEOUT 250
@@ -344,9 +350,17 @@ static const struct stm32l4_rev stm32g49_g4axx_revs[] = {
{ 0x1000, "A" },
};
+static const struct stm32l4_rev stm32u53_u54xx_revs[] = {
+ { 0x1000, "A" }, { 0x1001, "Z" },
+};
+
static const struct stm32l4_rev stm32u57_u58xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2000, "B" },
- { 0x2001, "X" }, { 0x3000, "C" },
+ { 0x2001, "X" }, { 0x3000, "C" }, { 0x3001, "W" },
+};
+
+static const struct stm32l4_rev stm32u59_u5axx_revs[] = {
+ { 0x3001, "X" },
};
static const struct stm32l4_rev stm32wba5x_revs[] = {
@@ -419,6 +433,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
.otp_size = 1024,
},
{
+ .id = DEVID_STM32U53_U54XX,
+ .revs = stm32u53_u54xx_revs,
+ .num_revs = ARRAY_SIZE(stm32u53_u54xx_revs),
+ .device_str = "STM32U535/U545",
+ .max_flash_size_kb = 512,
+ .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x0BFA07A0,
+ .otp_base = 0x0BFA0000,
+ .otp_size = 512,
+ },
+ {
.id = DEVID_STM32G05_G06XX,
.revs = stm32g05_g06xx_revs,
.num_revs = ARRAY_SIZE(stm32g05_g06xx_revs),
@@ -575,6 +601,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
.otp_size = 1024,
},
{
+ .id = DEVID_STM32U59_U5AXX,
+ .revs = stm32u59_u5axx_revs,
+ .num_revs = ARRAY_SIZE(stm32u59_u5axx_revs),
+ .device_str = "STM32U59/U5Axx",
+ .max_flash_size_kb = 4096,
+ .flags = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,
+ .flash_regs_base = 0x40022000,
+ .fsize_addr = 0x0BFA07A0,
+ .otp_base = 0x0BFA0000,
+ .otp_size = 512,
+ },
+ {
.id = DEVID_STM32U57_U58XX,
.revs = stm32u57_u58xx_revs,
.num_revs = ARRAY_SIZE(stm32u57_u58xx_revs),
@@ -2000,10 +2038,22 @@ static int stm32l4_probe(struct flash_bank *bank)
stm32l4_info->bank1_sectors = num_pages / 2;
}
break;
+ case DEVID_STM32U53_U54XX:
case DEVID_STM32U57_U58XX:
- /* if flash size is max (2M) the device is always dual bank
- * otherwise check DUALBANK
+ case DEVID_STM32U59_U5AXX:
+ /* according to RM0456 Rev 4, Chapter 7.3.1 and 7.9.13
+ * U53x/U54x have 512K max flash size:
+ * 512K variants are always in DUAL BANK mode
+ * 256K and 128K variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * U57x/U58x have 2M max flash size:
+ * 2M variants are always in DUAL BANK mode
+ * 1M variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * U59x/U5Ax have 4M max flash size:
+ * 4M variants are always in DUAL BANK mode
+ * 2M variants can be in DUAL BANK mode if FLASH_OPTR:DUALBANK is set
+ * Note: flash banks are always contiguous
*/
+
page_size_kb = 8;
num_pages = flash_size_kb / page_size_kb;
stm32l4_info->bank1_sectors = num_pages;
diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h
index 3dc0909..5f3bc26 100644
--- a/src/flash/nor/stm32l4x.h
+++ b/src/flash/nor/stm32l4x.h
@@ -89,6 +89,7 @@
#define DEVID_STM32L43_L44XX 0x435
#define DEVID_STM32C01XX 0x443
#define DEVID_STM32C03XX 0x453
+#define DEVID_STM32U53_U54XX 0x455
#define DEVID_STM32G05_G06XX 0x456
#define DEVID_STM32G07_G08XX 0x460
#define DEVID_STM32L49_L4AXX 0x461
@@ -102,6 +103,7 @@
#define DEVID_STM32L4P_L4QXX 0x471
#define DEVID_STM32L55_L56XX 0x472
#define DEVID_STM32G49_G4AXX 0x479
+#define DEVID_STM32U59_U5AXX 0x481
#define DEVID_STM32U57_U58XX 0x482
#define DEVID_STM32WBA5X 0x492
#define DEVID_STM32WB1XX 0x494
diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl
index 654f201..0dd84ef 100644
--- a/src/flash/startup.tcl
+++ b/src/flash/startup.tcl
@@ -5,7 +5,7 @@
#
# program utility proc
# usage: program filename
-# optional args: verify, reset, exit and address
+# optional args: preverify, verify, reset, exit and address
#
lappend _telnet_autocomplete_skip program_error
@@ -101,8 +101,8 @@ proc program {filename args} {
return
}
-add_help_text program "write an image to flash, address is only required for binary images. verify, reset, exit are optional"
-add_usage_text program "<filename> \[address\] \[pre-verify\] \[verify\] \[reset\] \[exit\]"
+add_help_text program "write an image to flash, address is only required for binary images. preverify, verify, reset, exit are optional"
+add_usage_text program "<filename> \[address\] \[preverify\] \[verify\] \[reset\] \[exit\]"
# stm32[f0x|f3x] uses the same flash driver as the stm32f1x
proc stm32f0x args { eval stm32f1x $args }
diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c
index 5f38b43..3e09143 100644
--- a/src/helper/binarybuffer.c
+++ b/src/helper/binarybuffer.c
@@ -102,7 +102,6 @@ bool buf_cmp_mask(const void *_buf1, const void *_buf2,
return buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing);
}
-
void *buf_set_ones(void *_buf, unsigned size)
{
uint8_t *buf = _buf;
@@ -206,36 +205,75 @@ char *buf_to_hex_str(const void *_buf, unsigned buf_len)
return str;
}
-/** identify radix, and skip radix-prefix (0, 0x or 0X) */
-static void str_radix_guess(const char **_str, unsigned *_str_len,
- unsigned *_radix)
+static bool str_has_hex_prefix(const char *s)
+{
+ /* Starts with "0x" or "0X" */
+ return (s[0] == '0') && (s[1] == 'x' || s[1] == 'X');
+}
+
+static bool str_has_octal_prefix(const char *s)
+{
+ /* - starts with '0',
+ * - has at least two characters, and
+ * - the second character is not 'x' or 'X' */
+ return (s[0] == '0') && (s[1] != '\0') && (s[1] != 'x') && (s[1] != 'X');
+}
+
+/**
+ * Try to identify the radix of the number by looking at its prefix.
+ * No further validation of the number is preformed.
+ */
+static unsigned int str_radix_guess(const char *str)
+{
+ assert(str);
+
+ if (str_has_hex_prefix(str))
+ return 16;
+
+ if (str_has_octal_prefix(str))
+ return 8;
+
+ /* Otherwise assume a decadic number. */
+ return 10;
+}
+
+/** Strip leading "0x" or "0X" from hex numbers or "0" from octal numbers. */
+static void str_strip_number_prefix_if_present(const char **_str, unsigned int radix)
{
- unsigned radix = *_radix;
- if (radix != 0)
- return;
+ assert(radix == 16 || radix == 10 || radix == 8);
+ assert(_str);
+
const char *str = *_str;
- unsigned str_len = *_str_len;
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
- radix = 16;
+ assert(str);
+
+ if (radix == 16 && str_has_hex_prefix(str))
str += 2;
- str_len -= 2;
- } else if ((str[0] == '0') && (str_len != 1)) {
- radix = 8;
+ else if (radix == 8 && str_has_octal_prefix(str))
str += 1;
- str_len -= 1;
- } else
- radix = 10;
+
+ /* No prefix to strip for radix == 10. */
+
*_str = str;
- *_str_len = str_len;
- *_radix = radix;
}
-int str_to_buf(const char *str, unsigned str_len,
- void *_buf, unsigned buf_len, unsigned radix)
+int str_to_buf(const char *str, void *_buf, unsigned int buf_len,
+ unsigned int radix, unsigned int *_detected_radix)
{
- str_radix_guess(&str, &str_len, &radix);
+ assert(radix == 0 || radix == 8 || radix == 10 || radix == 16);
+
+ if (radix == 0)
+ radix = str_radix_guess(str);
- float factor;
+ if (_detected_radix)
+ *_detected_radix = radix;
+
+ str_strip_number_prefix_if_present(&str, radix);
+
+ const size_t str_len = strlen(str);
+ if (str_len == 0)
+ return ERROR_INVALID_NUMBER;
+
+ float factor = 0.0;
if (radix == 16)
factor = 0.5; /* log(16) / log(256) = 0.5 */
else if (radix == 10)
@@ -243,41 +281,69 @@ int str_to_buf(const char *str, unsigned str_len,
else if (radix == 8)
factor = 0.375; /* log(8) / log(256) = 0.375 */
else
- return 0;
+ assert(false);
- /* copy to zero-terminated buffer */
- char *charbuf = strndup(str, str_len);
+ const unsigned int b256_len = ceil_f_to_u32(str_len * factor);
- /* number of digits in base-256 notation */
- unsigned b256_len = ceil_f_to_u32(str_len * factor);
+ /* Allocate a buffer for digits in base-256 notation */
uint8_t *b256_buf = calloc(b256_len, 1);
+ if (!b256_buf) {
+ LOG_ERROR("Unable to allocate memory");
+ return ERROR_FAIL;
+ }
- /* go through zero terminated buffer
- * input digits (ASCII) */
- unsigned i;
- for (i = 0; charbuf[i]; i++) {
- uint32_t tmp = charbuf[i];
- if ((tmp >= '0') && (tmp <= '9'))
+ /* Go through the zero-terminated buffer
+ * of input digits (ASCII) */
+ for (unsigned int i = 0; str[i]; i++) {
+ uint32_t tmp = str[i];
+ if ((tmp >= '0') && (tmp <= '9')) {
tmp = (tmp - '0');
- else if ((tmp >= 'a') && (tmp <= 'f'))
+ } else if ((tmp >= 'a') && (tmp <= 'f')) {
tmp = (tmp - 'a' + 10);
- else if ((tmp >= 'A') && (tmp <= 'F'))
+ } else if ((tmp >= 'A') && (tmp <= 'F')) {
tmp = (tmp - 'A' + 10);
- else
- continue; /* skip characters other than [0-9,a-f,A-F] */
+ } else {
+ /* Characters other than [0-9,a-f,A-F] are invalid */
+ free(b256_buf);
+ return ERROR_INVALID_NUMBER;
+ }
- if (tmp >= radix)
- continue; /* skip digits invalid for the current radix */
+ if (tmp >= radix) {
+ /* Encountered a digit that is invalid for the current radix */
+ free(b256_buf);
+ return ERROR_INVALID_NUMBER;
+ }
- /* base-256 digits */
- for (unsigned j = 0; j < b256_len; j++) {
+ /* Add the current digit (tmp) to the intermediate result
+ * in b256_buf (base-256 digits) */
+ for (unsigned int j = 0; j < b256_len; j++) {
tmp += (uint32_t)b256_buf[j] * radix;
- b256_buf[j] = (uint8_t)(tmp & 0xFF);
+ b256_buf[j] = (uint8_t)(tmp & 0xFFu);
tmp >>= 8;
}
+ /* The b256_t buffer is large enough to contain the whole result. */
+ assert(tmp == 0);
}
+ /* The result must not contain more bits than buf_len. */
+ /* Check the whole bytes: */
+ for (unsigned int j = DIV_ROUND_UP(buf_len, 8); j < b256_len; j++) {
+ if (b256_buf[j] != 0x0) {
+ free(b256_buf);
+ return ERROR_NUMBER_EXCEEDS_BUFFER;
+ }
+ }
+ /* Check the partial byte: */
+ if (buf_len % 8) {
+ const uint8_t mask = 0xFFu << (buf_len % 8);
+ if ((b256_buf[(buf_len / 8)] & mask) != 0x0) {
+ free(b256_buf);
+ return ERROR_NUMBER_EXCEEDS_BUFFER;
+ }
+ }
+
+ /* Copy the digits to the output buffer */
uint8_t *buf = _buf;
for (unsigned j = 0; j < DIV_ROUND_UP(buf_len, 8); j++) {
if (j < b256_len)
@@ -286,14 +352,8 @@ int str_to_buf(const char *str, unsigned str_len,
buf[j] = 0;
}
- /* mask out bits that don't belong to the buffer */
- if (buf_len % 8)
- buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8));
-
free(b256_buf);
- free(charbuf);
-
- return i;
+ return ERROR_OK;
}
void bit_copy_queue_init(struct bit_copy_queue *q)
diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h
index 3446296..4413743 100644
--- a/src/helper/binarybuffer.h
+++ b/src/helper/binarybuffer.h
@@ -14,6 +14,9 @@
#include <helper/list.h>
#include <helper/types.h>
+#define ERROR_INVALID_NUMBER (-1700)
+#define ERROR_NUMBER_EXCEEDS_BUFFER (-1701)
+
/** @file
* Support functions to access arbitrary bits in a byte array
*/
@@ -189,8 +192,18 @@ void *buf_set_ones(void *buf, unsigned size);
void *buf_set_buf(const void *src, unsigned src_start,
void *dst, unsigned dst_start, unsigned len);
-int str_to_buf(const char *str, unsigned len,
- void *bin_buf, unsigned buf_size, unsigned radix);
+/**
+ * Parse an unsigned number (provided as a zero-terminated string)
+ * into a bit buffer whose size is buf_len bits.
+ * @param str Input number, zero-terminated string
+ * @param _buf Output buffer, allocated by the caller
+ * @param buf_len Output buffer size in bits
+ * @param radix Base of the input number - 16, 10, 8 or 0.
+ * 0 means auto-detect the radix.
+ */
+int str_to_buf(const char *str, void *_buf, unsigned int buf_len,
+ unsigned int radix, unsigned int *_detected_radix);
+
char *buf_to_hex_str(const void *buf, unsigned size);
/* read a uint32_t from a buffer in target memory endianness */
diff --git a/src/helper/command.c b/src/helper/command.c
index a775c73..15a9b4a 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -1360,6 +1360,46 @@ int command_parse_bool_arg(const char *in, bool *out)
return ERROR_COMMAND_SYNTAX_ERROR;
}
+static const char *radix_to_str(unsigned int radix)
+{
+ switch (radix) {
+ case 16: return "hexadecimal";
+ case 10: return "decadic";
+ case 8: return "octal";
+ }
+ assert(false);
+ return "";
+}
+
+COMMAND_HELPER(command_parse_str_to_buf, const char *str, void *buf, unsigned int buf_len,
+ unsigned int radix)
+{
+ assert(str);
+ assert(buf);
+
+ int ret = str_to_buf(str, buf, buf_len, radix, NULL);
+ if (ret == ERROR_OK)
+ return ret;
+
+ /* Provide a clear error message to the user */
+ if (ret == ERROR_INVALID_NUMBER) {
+ if (radix == 0) {
+ /* Any radix is accepted, so don't include it in the error message. */
+ command_print(CMD, "'%s' is not a valid number", str);
+ } else {
+ /* Specific radix is required - tell the user what it is. */
+ command_print(CMD, "'%s' is not a valid number (requiring %s number)",
+ str, radix_to_str(radix));
+ }
+ } else if (ret == ERROR_NUMBER_EXCEEDS_BUFFER) {
+ command_print(CMD, "Number %s exceeds %u bits", str, buf_len);
+ } else {
+ command_print(CMD, "Could not parse number '%s'", str);
+ }
+
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+}
+
COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label)
{
switch (CMD_ARGC) {
diff --git a/src/helper/command.h b/src/helper/command.h
index fc26dda..7a044e6 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -517,6 +517,17 @@ DECLARE_PARSE_WRAPPER(_target_addr, target_addr_t);
int command_parse_bool_arg(const char *in, bool *out);
COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label);
+/**
+ * Parse a number (base 10, base 16 or base 8) and store the result
+ * into a bit buffer.
+ *
+ * In case of parsing error, a user-readable error message is produced.
+ *
+ * If radix = 0 is given, the function guesses the radix by looking at the number prefix.
+ */
+COMMAND_HELPER(command_parse_str_to_buf, const char *str, void *buf, unsigned int buf_len,
+ unsigned int radix);
+
/** parses an on/off command argument */
#define COMMAND_PARSE_ON_OFF(in, out) \
COMMAND_PARSE_BOOL(in, out, "on", "off")
diff --git a/src/helper/jep106.inc b/src/helper/jep106.inc
index 958dc4e..b74cda8 100644
--- a/src/helper/jep106.inc
+++ b/src/helper/jep106.inc
@@ -8,9 +8,7 @@
* identification code list, please visit the JEDEC website at www.jedec.org .
*/
-/* This file is aligned to revision JEP106BI January 2024. */
-
-/* "NXP (Philips)" is reported below, while missing since JEP106BG */
+/* This file is aligned to revision JEP106BJ.01 July 2024. */
[0][0x01 - 1] = "AMD",
[0][0x02 - 1] = "AMI",
@@ -30,7 +28,7 @@
[0][0x10 - 1] = "NEC",
[0][0x11 - 1] = "RCA",
[0][0x12 - 1] = "Raytheon",
-[0][0x13 - 1] = "Conexant (Rockwell)",
+[0][0x13 - 1] = "Synaptics",
[0][0x14 - 1] = "Seeq",
[0][0x15 - 1] = "NXP (Philips)",
[0][0x16 - 1] = "Synertek",
@@ -1045,7 +1043,7 @@
[8][0x17 - 1] = "Axell Corporation",
[8][0x18 - 1] = "Essencore Limited",
[8][0x19 - 1] = "Phytium",
-[8][0x1a - 1] = "Xi'an UniIC Semiconductors Co Ltd",
+[8][0x1a - 1] = "UniIC Semiconductors Co Ltd",
[8][0x1b - 1] = "Ambiq Micro",
[8][0x1c - 1] = "eveRAM Technology Inc",
[8][0x1d - 1] = "Infomax",
@@ -1452,7 +1450,7 @@
[11][0x34 - 1] = "Acacia Communications",
[11][0x35 - 1] = "Beijinjinshengyihe Technology Co Ltd",
[11][0x36 - 1] = "Zyzyx",
-[11][0x37 - 1] = "T-HEAD Semiconductor Co Ltd",
+[11][0x37 - 1] = "C-SKY Microsystems Co Ltd",
[11][0x38 - 1] = "Shenzhen Hystou Technology Co Ltd",
[11][0x39 - 1] = "Syzexion",
[11][0x3a - 1] = "Kembona",
@@ -1938,4 +1936,31 @@
[15][0x22 - 1] = "SkyeChip",
[15][0x23 - 1] = "Guangzhou Kaishile Trading Co Ltd",
[15][0x24 - 1] = "Jing Pai Digital Technology (Shenzhen) Co",
+[15][0x25 - 1] = "Memoritek",
+[15][0x26 - 1] = "Zhejiang Hikstor Technology Co Ltd",
+[15][0x27 - 1] = "Memoritek PTE Ltd",
+[15][0x28 - 1] = "Longsailing Semiconductor Co Ltd",
+[15][0x29 - 1] = "LX Semicon",
+[15][0x2a - 1] = "Shenzhen Techwinsemi Technology Co Ltd",
+[15][0x2b - 1] = "AOC",
+[15][0x2c - 1] = "GOEPEL Electronic GmbH",
+[15][0x2d - 1] = "Shenzhen G-Bong Technology Co Ltd",
+[15][0x2e - 1] = "Openedges Technology Inc",
+[15][0x2f - 1] = "EA Semi Shangahi Limited",
+[15][0x30 - 1] = "EMBCORF",
+[15][0x31 - 1] = "Shenzhen MicroBT Electronics Technology",
+[15][0x32 - 1] = "Shanghai Simor Chip Semiconductor Co",
+[15][0x33 - 1] = "Xllbyte",
+[15][0x34 - 1] = "Guangzhou Maidite Electronics Co Ltd.",
+[15][0x35 - 1] = "Zhejiang Changchun Technology Co Ltd",
+[15][0x36 - 1] = "Beijing Cloud Security Technology Co Ltd",
+[15][0x37 - 1] = "SSTC Technology and Distribution Inc",
+[15][0x38 - 1] = "Shenzhen Panmin Technology Co Ltd",
+[15][0x39 - 1] = "ITE Tech Inc",
+[15][0x3a - 1] = "Beijing Zettastone Technology Co Ltd",
+[15][0x3b - 1] = "Powerchip Micro Device",
+[15][0x3c - 1] = "Shenzhen Ysemi Computing Co Ltd",
+[15][0x3d - 1] = "Shenzhen Titan Micro Electronics Co Ltd",
+[15][0x3e - 1] = "Shenzhen Macroflash Technology Co Ltd",
+[15][0x3f - 1] = "Advantech Group",
/* EOF */
diff --git a/src/jtag/commands.c b/src/jtag/commands.c
index a60684c..1bca4e8 100644
--- a/src/jtag/commands.c
+++ b/src/jtag/commands.c
@@ -166,10 +166,9 @@ void jtag_scan_field_clone(struct scan_field *dst, const struct scan_field *src)
enum scan_type jtag_scan_type(const struct scan_command *cmd)
{
- int i;
int type = 0;
- for (i = 0; i < cmd->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->num_fields; i++) {
if (cmd->fields[i].in_value)
type |= SCAN_IN;
if (cmd->fields[i].out_value)
@@ -179,13 +178,12 @@ enum scan_type jtag_scan_type(const struct scan_command *cmd)
return type;
}
-int jtag_scan_size(const struct scan_command *cmd)
+unsigned int jtag_scan_size(const struct scan_command *cmd)
{
- int bit_count = 0;
- int i;
+ unsigned int bit_count = 0;
/* count bits in scan command */
- for (i = 0; i < cmd->num_fields; i++)
+ for (unsigned int i = 0; i < cmd->num_fields; i++)
bit_count += cmd->fields[i].num_bits;
return bit_count;
@@ -193,19 +191,16 @@ int jtag_scan_size(const struct scan_command *cmd)
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
{
- int bit_count = 0;
- int i;
-
- bit_count = jtag_scan_size(cmd);
+ unsigned int bit_count = jtag_scan_size(cmd);
*buffer = calloc(1, DIV_ROUND_UP(bit_count, 8));
bit_count = 0;
- LOG_DEBUG_IO("%s num_fields: %i",
+ LOG_DEBUG_IO("%s num_fields: %u",
cmd->ir_scan ? "IRSCAN" : "DRSCAN",
cmd->num_fields);
- for (i = 0; i < cmd->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->num_fields; i++) {
if (cmd->fields[i].out_value) {
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {
char *char_buf = buf_to_hex_str(cmd->fields[i].out_value,
@@ -213,14 +208,14 @@ int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
? DEBUG_JTAG_IOZ
: cmd->fields[i].num_bits);
- LOG_DEBUG("fields[%i].out_value[%i]: 0x%s", i,
+ LOG_DEBUG("fields[%u].out_value[%u]: 0x%s", i,
cmd->fields[i].num_bits, char_buf);
free(char_buf);
}
buf_set_buf(cmd->fields[i].out_value, 0, *buffer,
bit_count, cmd->fields[i].num_bits);
} else {
- LOG_DEBUG_IO("fields[%i].out_value[%i]: NULL",
+ LOG_DEBUG_IO("fields[%u].out_value[%u]: NULL",
i, cmd->fields[i].num_bits);
}
@@ -234,19 +229,18 @@ int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd)
{
- int i;
int bit_count = 0;
int retval;
/* we return ERROR_OK, unless a check fails, or a handler reports a problem */
retval = ERROR_OK;
- for (i = 0; i < cmd->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->num_fields; i++) {
/* if neither in_value nor in_handler
* are specified we don't have to examine this field
*/
if (cmd->fields[i].in_value) {
- int num_bits = cmd->fields[i].num_bits;
+ const unsigned int num_bits = cmd->fields[i].num_bits;
uint8_t *captured = buf_set_buf(buffer, bit_count,
malloc(DIV_ROUND_UP(num_bits, 8)), 0, num_bits);
@@ -256,7 +250,7 @@ int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd)
? DEBUG_JTAG_IOZ
: num_bits);
- LOG_DEBUG("fields[%i].in_value[%i]: 0x%s",
+ LOG_DEBUG("fields[%u].in_value[%u]: 0x%s",
i, num_bits, char_buf);
free(char_buf);
}
diff --git a/src/jtag/commands.h b/src/jtag/commands.h
index 8259077..29fa842 100644
--- a/src/jtag/commands.h
+++ b/src/jtag/commands.h
@@ -36,7 +36,7 @@ struct scan_command {
/** instruction/not data scan */
bool ir_scan;
/** number of fields in *fields array */
- int num_fields;
+ unsigned int num_fields;
/** pointer to an array of data scan fields */
struct scan_field *fields;
/** state in which JTAG commands should finish */
@@ -50,14 +50,14 @@ struct statemove_command {
struct pathmove_command {
/** number of states in *path */
- int num_states;
+ unsigned int num_states;
/** states that have to be passed */
tap_state_t *path;
};
struct runtest_command {
/** number of cycles to spend in Run-Test/Idle state */
- int num_cycles;
+ unsigned int num_cycles;
/** state in which JTAG commands should finish */
tap_state_t end_state;
};
@@ -65,7 +65,7 @@ struct runtest_command {
struct stableclocks_command {
/** number of clock cycles that should be sent */
- int num_cycles;
+ unsigned int num_cycles;
};
@@ -100,7 +100,7 @@ struct sleep_command {
*/
struct tms_command {
/** How many bits should be clocked out. */
- unsigned num_bits;
+ unsigned int num_bits;
/** The bits to clock out; the LSB is bit 0 of bits[0]. */
const uint8_t *bits;
};
@@ -157,7 +157,7 @@ struct jtag_command *jtag_command_queue_get(void);
void jtag_scan_field_clone(struct scan_field *dst, const struct scan_field *src);
enum scan_type jtag_scan_type(const struct scan_command *cmd);
-int jtag_scan_size(const struct scan_command *cmd);
+unsigned int jtag_scan_size(const struct scan_command *cmd);
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd);
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer);
diff --git a/src/jtag/core.c b/src/jtag/core.c
index c84d5aa..9eae5e7 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -39,7 +39,7 @@
#include "server/ipdbg.h"
/** The number of JTAG queue flushes (for profiling and debugging purposes). */
-static int jtag_flush_queue_count;
+static unsigned int jtag_flush_queue_count;
/* Sleep this # of ms after flushing the queue */
static int jtag_flush_queue_sleep;
@@ -88,14 +88,14 @@ static enum reset_types jtag_reset_config = RESET_NONE;
tap_state_t cmd_queue_cur_state = TAP_RESET;
static bool jtag_verify_capture_ir = true;
-static int jtag_verify = 1;
+static bool jtag_verify = true;
/* how long the OpenOCD should wait before attempting JTAG communication after reset lines
*deasserted (in ms) */
-static int adapter_nsrst_delay; /* default to no nSRST delay */
-static int jtag_ntrst_delay;/* default to no nTRST delay */
-static int adapter_nsrst_assert_width; /* width of assertion */
-static int jtag_ntrst_assert_width; /* width of assertion */
+static unsigned int adapter_nsrst_delay; /* default to no nSRST delay */
+static unsigned int jtag_ntrst_delay;/* default to no nTRST delay */
+static unsigned int adapter_nsrst_assert_width; /* width of assertion */
+static unsigned int jtag_ntrst_assert_width; /* width of assertion */
/**
* Contains a single callback along with a pointer that will be passed
@@ -186,10 +186,10 @@ struct jtag_tap *jtag_all_taps(void)
return __jtag_all_taps;
};
-unsigned jtag_tap_count(void)
+unsigned int jtag_tap_count(void)
{
struct jtag_tap *t = jtag_all_taps();
- unsigned n = 0;
+ unsigned int n = 0;
while (t) {
n++;
t = t->next_tap;
@@ -197,10 +197,10 @@ unsigned jtag_tap_count(void)
return n;
}
-unsigned jtag_tap_count_enabled(void)
+unsigned int jtag_tap_count_enabled(void)
{
struct jtag_tap *t = jtag_all_taps();
- unsigned n = 0;
+ unsigned int n = 0;
while (t) {
if (t->enabled)
n++;
@@ -212,7 +212,7 @@ unsigned jtag_tap_count_enabled(void)
/** Append a new TAP to the chain of all taps. */
static void jtag_tap_add(struct jtag_tap *t)
{
- unsigned jtag_num_taps = 0;
+ unsigned int jtag_num_taps = 0;
struct jtag_tap **tap = &__jtag_all_taps;
while (*tap) {
@@ -499,7 +499,7 @@ void jtag_add_tlr(void)
*
* @todo Update naming conventions to stop assuming everything is JTAG.
*/
-int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state)
+int jtag_add_tms_seq(unsigned int nbits, const uint8_t *seq, enum tap_state state)
{
int retval;
@@ -514,7 +514,7 @@ int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state)
return retval;
}
-void jtag_add_pathmove(int num_states, const tap_state_t *path)
+void jtag_add_pathmove(unsigned int num_states, const tap_state_t *path)
{
tap_state_t cur_state = cmd_queue_cur_state;
@@ -525,7 +525,7 @@ void jtag_add_pathmove(int num_states, const tap_state_t *path)
return;
}
- for (int i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == TAP_RESET) {
LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences");
jtag_set_error(ERROR_JTAG_STATE_INVALID);
@@ -567,12 +567,12 @@ int jtag_add_statemove(tap_state_t goal_state)
/* nothing to do */;
else if (tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state)) {
- unsigned tms_bits = tap_get_tms_path(cur_state, goal_state);
- unsigned tms_count = tap_get_tms_path_len(cur_state, goal_state);
+ unsigned int tms_bits = tap_get_tms_path(cur_state, goal_state);
+ unsigned int tms_count = tap_get_tms_path_len(cur_state, goal_state);
tap_state_t moves[8];
assert(tms_count < ARRAY_SIZE(moves));
- for (unsigned i = 0; i < tms_count; i++, tms_bits >>= 1) {
+ for (unsigned int i = 0; i < tms_count; i++, tms_bits >>= 1) {
bool bit = tms_bits & 1;
cur_state = tap_state_transition(cur_state, bit);
@@ -589,14 +589,14 @@ int jtag_add_statemove(tap_state_t goal_state)
return ERROR_OK;
}
-void jtag_add_runtest(int num_cycles, tap_state_t state)
+void jtag_add_runtest(unsigned int num_cycles, tap_state_t state)
{
jtag_prelude(state);
jtag_set_error(interface_jtag_add_runtest(num_cycles, state));
}
-void jtag_add_clocks(int num_cycles)
+void jtag_add_clocks(unsigned int num_cycles)
{
if (!tap_is_state_stable(cmd_queue_cur_state)) {
LOG_ERROR("jtag_add_clocks() called with TAP in unstable state \"%s\"",
@@ -960,16 +960,16 @@ int default_interface_jtag_execute_queue(void)
LOG_DEBUG_IO("JTAG %s SCAN to %s",
cmd->cmd.scan->ir_scan ? "IR" : "DR",
tap_state_name(cmd->cmd.scan->end_state));
- for (int i = 0; i < cmd->cmd.scan->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++) {
struct scan_field *field = cmd->cmd.scan->fields + i;
if (field->out_value) {
char *str = buf_to_hex_str(field->out_value, field->num_bits);
- LOG_DEBUG_IO(" %db out: %s", field->num_bits, str);
+ LOG_DEBUG_IO(" %ub out: %s", field->num_bits, str);
free(str);
}
if (field->in_value) {
char *str = buf_to_hex_str(field->in_value, field->num_bits);
- LOG_DEBUG_IO(" %db in: %s", field->num_bits, str);
+ LOG_DEBUG_IO(" %ub in: %s", field->num_bits, str);
free(str);
}
}
@@ -1029,7 +1029,7 @@ void jtag_execute_queue_noclear(void)
}
}
-int jtag_get_flush_queue_count(void)
+unsigned int jtag_get_flush_queue_count(void)
{
return jtag_flush_queue_count;
}
@@ -1081,7 +1081,7 @@ void jtag_sleep(uint32_t us)
/* a larger IR length than we ever expect to autoprobe */
#define JTAG_IRLEN_MAX 60
-static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode)
+static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned int num_idcode)
{
struct scan_field field = {
.num_bits = num_idcode * 32,
@@ -1090,7 +1090,7 @@ static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcod
};
/* initialize to the end of chain ID value */
- for (unsigned i = 0; i < num_idcode; i++)
+ for (unsigned int i = 0; i < num_idcode; i++)
buf_set_u32(idcode_buffer, i * 32, 32, END_OF_CHAIN_FLAG);
jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value, TAP_DRPAUSE);
@@ -1098,12 +1098,12 @@ static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcod
return jtag_execute_queue();
}
-static bool jtag_examine_chain_check(uint8_t *idcodes, unsigned count)
+static bool jtag_examine_chain_check(uint8_t *idcodes, unsigned int count)
{
uint8_t zero_check = 0x0;
uint8_t one_check = 0xff;
- for (unsigned i = 0; i < count * 4; i++) {
+ for (unsigned int i = 0; i < count * 4; i++) {
zero_check |= idcodes[i];
one_check &= idcodes[i];
}
@@ -1158,7 +1158,8 @@ static bool jtag_idcode_is_final(uint32_t idcode)
* with the JTAG chain earlier, gives more helpful/explicit error messages.
* Returns TRUE iff garbage was found.
*/
-static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned max)
+static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned int count,
+ unsigned int max)
{
bool triggered = false;
for (; count < max - 31; count += 32) {
@@ -1185,26 +1186,26 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
uint32_t idcode = tap->idcode & mask;
/* Loop over the expected identification codes and test for a match */
- for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {
- uint32_t expected = tap->expected_ids[ii] & mask;
+ for (unsigned int i = 0; i < tap->expected_ids_cnt; i++) {
+ uint32_t expected = tap->expected_ids[i] & mask;
if (idcode == expected)
return true;
/* treat "-expected-id 0" as a "don't-warn" wildcard */
- if (tap->expected_ids[ii] == 0)
+ if (tap->expected_ids[i] == 0)
return true;
}
/* If none of the expected ids matched, warn */
jtag_examine_chain_display(LOG_LVL_WARNING, "UNEXPECTED",
tap->dotted_name, tap->idcode);
- for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {
+ for (unsigned int i = 0; i < tap->expected_ids_cnt; i++) {
char msg[32];
- snprintf(msg, sizeof(msg), "expected %u of %u", ii + 1, tap->expected_ids_cnt);
+ snprintf(msg, sizeof(msg), "expected %u of %u", i + 1, tap->expected_ids_cnt);
jtag_examine_chain_display(LOG_LVL_ERROR, msg,
- tap->dotted_name, tap->expected_ids[ii]);
+ tap->dotted_name, tap->expected_ids[i]);
}
return false;
}
@@ -1215,7 +1216,7 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
static int jtag_examine_chain(void)
{
int retval;
- unsigned max_taps = jtag_tap_count();
+ unsigned int max_taps = jtag_tap_count();
/* Autoprobe up to this many. */
if (max_taps < JTAG_MAX_AUTO_TAPS)
@@ -1243,9 +1244,9 @@ static int jtag_examine_chain(void)
/* Point at the 1st predefined tap, if any */
struct jtag_tap *tap = jtag_tap_next_enabled(NULL);
- unsigned bit_count = 0;
- unsigned autocount = 0;
- for (unsigned i = 0; i < max_taps; i++) {
+ unsigned int bit_count = 0;
+ unsigned int autocount = 0;
+ for (unsigned int i = 0; i < max_taps; i++) {
assert(bit_count < max_taps * 32);
uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32);
@@ -1337,7 +1338,7 @@ static int jtag_validate_ircapture(void)
int retval;
/* when autoprobing, accommodate huge IR lengths */
- int total_ir_length = 0;
+ unsigned int total_ir_length = 0;
for (tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {
if (tap->ir_length == 0)
total_ir_length += JTAG_IRLEN_MAX;
@@ -1396,7 +1397,7 @@ static int jtag_validate_ircapture(void)
&& tap->ir_length < JTAG_IRLEN_MAX) {
tap->ir_length++;
}
- LOG_WARNING("AUTO %s - use \"jtag newtap %s %s -irlen %d "
+ LOG_WARNING("AUTO %s - use \"jtag newtap %s %s -irlen %u "
"-expected-id 0x%08" PRIx32 "\"",
tap->dotted_name, tap->chip, tap->tapname, tap->ir_length, tap->idcode);
}
@@ -1445,8 +1446,8 @@ done:
void jtag_tap_init(struct jtag_tap *tap)
{
- unsigned ir_len_bits;
- unsigned ir_len_bytes;
+ unsigned int ir_len_bits;
+ unsigned int ir_len_bytes;
/* if we're autoprobing, cope with potentially huge ir_length */
ir_len_bits = tap->ir_length ? tap->ir_length : JTAG_IRLEN_MAX;
@@ -1471,8 +1472,8 @@ void jtag_tap_init(struct jtag_tap *tap)
jtag_register_event_callback(&jtag_reset_callback, tap);
jtag_tap_add(tap);
- LOG_DEBUG("Created Tap: %s @ abs position %d, "
- "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name,
+ LOG_DEBUG("Created Tap: %s @ abs position %u, "
+ "irlen %u, capture: 0x%x mask: 0x%x", tap->dotted_name,
tap->abs_chain_position, tap->ir_length,
(unsigned) tap->ir_capture_value,
(unsigned) tap->ir_capture_mask);
@@ -1749,37 +1750,36 @@ int jtag_get_srst(void)
return jtag_srst == 1;
}
-void jtag_set_nsrst_delay(unsigned delay)
+void jtag_set_nsrst_delay(unsigned int delay)
{
adapter_nsrst_delay = delay;
}
-unsigned jtag_get_nsrst_delay(void)
+unsigned int jtag_get_nsrst_delay(void)
{
return adapter_nsrst_delay;
}
-void jtag_set_ntrst_delay(unsigned delay)
+void jtag_set_ntrst_delay(unsigned int delay)
{
jtag_ntrst_delay = delay;
}
-unsigned jtag_get_ntrst_delay(void)
+unsigned int jtag_get_ntrst_delay(void)
{
return jtag_ntrst_delay;
}
-
-void jtag_set_nsrst_assert_width(unsigned delay)
+void jtag_set_nsrst_assert_width(unsigned int delay)
{
adapter_nsrst_assert_width = delay;
}
-unsigned jtag_get_nsrst_assert_width(void)
+unsigned int jtag_get_nsrst_assert_width(void)
{
return adapter_nsrst_assert_width;
}
-void jtag_set_ntrst_assert_width(unsigned delay)
+void jtag_set_ntrst_assert_width(unsigned int delay)
{
jtag_ntrst_assert_width = delay;
}
-unsigned jtag_get_ntrst_assert_width(void)
+unsigned int jtag_get_ntrst_assert_width(void)
{
return jtag_ntrst_assert_width;
}
diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c
index b28ce62..489cb24 100644
--- a/src/jtag/drivers/amt_jtagaccel.c
+++ b/src/jtag/drivers/amt_jtagaccel.c
@@ -203,7 +203,7 @@ static void amt_jtagaccel_state_move(void)
tap_set_state(end_state);
}
-static void amt_jtagaccel_runtest(int num_cycles)
+static void amt_jtagaccel_runtest(unsigned int num_cycles)
{
int i = 0;
uint8_t aw_scan_tms_5;
diff --git a/src/jtag/drivers/angie.c b/src/jtag/drivers/angie.c
index 81dd1af..47628fe 100644
--- a/src/jtag/drivers/angie.c
+++ b/src/jtag/drivers/angie.c
@@ -1836,15 +1836,17 @@ static int angie_reset(int trst, int srst)
*/
static int angie_queue_pathmove(struct angie *device, struct jtag_command *cmd)
{
- int ret, i, num_states, batch_size, state_count;
+ int ret, state_count;
tap_state_t *path;
uint8_t tms_sequence;
- num_states = cmd->cmd.pathmove->num_states;
+ unsigned int num_states = cmd->cmd.pathmove->num_states;
path = cmd->cmd.pathmove->path;
state_count = 0;
while (num_states > 0) {
+ unsigned int batch_size;
+
tms_sequence = 0;
/* Determine batch size */
@@ -1853,7 +1855,7 @@ static int angie_queue_pathmove(struct angie *device, struct jtag_command *cmd)
else
batch_size = num_states;
- for (i = 0; i < batch_size; i++) {
+ for (unsigned int i = 0; i < batch_size; i++) {
if (tap_state_transition(tap_get_state(), false) == path[state_count]) {
/* Append '0' transition: clear bit 'i' in tms_sequence */
buf_set_u32(&tms_sequence, i, 1, 0x0);
@@ -1908,14 +1910,13 @@ static int angie_queue_sleep(struct angie *device, struct jtag_command *cmd)
static int angie_queue_stableclocks(struct angie *device, struct jtag_command *cmd)
{
int ret;
- unsigned int num_cycles;
if (!tap_is_state_stable(tap_get_state())) {
LOG_ERROR("JTAG_STABLECLOCKS: state not stable");
return ERROR_FAIL;
}
- num_cycles = cmd->cmd.stableclocks->num_cycles;
+ unsigned int num_cycles = cmd->cmd.stableclocks->num_cycles;
/* TMS stays either high (Test Logic Reset state) or low (all other states) */
if (tap_get_state() == TAP_RESET)
diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c
index 4c50c54..aaed16d 100644
--- a/src/jtag/drivers/arm-jtag-ew.c
+++ b/src/jtag/drivers/arm-jtag-ew.c
@@ -44,8 +44,8 @@ static uint8_t usb_out_buffer[ARMJTAGEW_OUT_BUFFER_SIZE];
/* Queue command functions */
static void armjtagew_end_state(tap_state_t state);
static void armjtagew_state_move(void);
-static void armjtagew_path_move(int num_states, tap_state_t *path);
-static void armjtagew_runtest(int num_cycles);
+static void armjtagew_path_move(unsigned int num_states, tap_state_t *path);
+static void armjtagew_runtest(unsigned int num_cycles);
static void armjtagew_scan(bool ir_scan,
enum scan_type type,
uint8_t *buffer,
@@ -95,7 +95,7 @@ static int armjtagew_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i",
+ LOG_DEBUG_IO("runtest %u cycles, end in %i",
cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
@@ -111,7 +111,7 @@ static int armjtagew_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
@@ -279,11 +279,9 @@ static void armjtagew_state_move(void)
tap_set_state(tap_get_end_state());
}
-static void armjtagew_path_move(int num_states, tap_state_t *path)
+static void armjtagew_path_move(unsigned int num_states, tap_state_t *path)
{
- int i;
-
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
/*
* TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode.
* Either handle that here, or update the documentation with examples
@@ -305,10 +303,8 @@ static void armjtagew_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-static void armjtagew_runtest(int num_cycles)
+static void armjtagew_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in IDLE */
@@ -318,7 +314,7 @@ static void armjtagew_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
armjtagew_tap_append_step(0, 0);
/* finish in end_state */
diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c
index 3d839e6..e416592 100644
--- a/src/jtag/drivers/bitbang.c
+++ b/src/jtag/drivers/bitbang.c
@@ -33,7 +33,7 @@
* this function checks the current stable state to decide on the value of TMS
* to use.
*/
-static int bitbang_stableclocks(int num_cycles);
+static int bitbang_stableclocks(unsigned int num_cycles);
static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);
@@ -95,7 +95,7 @@ static int bitbang_execute_tms(struct jtag_command *cmd)
unsigned num_bits = cmd->cmd.tms->num_bits;
const uint8_t *bits = cmd->cmd.tms->bits;
- LOG_DEBUG_IO("TMS: %d bits", num_bits);
+ LOG_DEBUG_IO("TMS: %u bits", num_bits);
int tms = 0;
for (unsigned i = 0; i < num_bits; i++) {
@@ -113,7 +113,7 @@ static int bitbang_execute_tms(struct jtag_command *cmd)
static int bitbang_path_move(struct pathmove_command *cmd)
{
- int num_states = cmd->num_states;
+ unsigned int num_states = cmd->num_states;
int state_count;
int tms = 0;
@@ -147,10 +147,8 @@ static int bitbang_path_move(struct pathmove_command *cmd)
return ERROR_OK;
}
-static int bitbang_runtest(int num_cycles)
+static int bitbang_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in IDLE */
@@ -161,7 +159,7 @@ static int bitbang_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
if (bitbang_interface->write(0, 0, 0) != ERROR_OK)
return ERROR_FAIL;
if (bitbang_interface->write(1, 0, 0) != ERROR_OK)
@@ -179,13 +177,12 @@ static int bitbang_runtest(int num_cycles)
return ERROR_OK;
}
-static int bitbang_stableclocks(int num_cycles)
+static int bitbang_stableclocks(unsigned int num_cycles)
{
int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
- int i;
/* send num_cycles clocks onto the cable */
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
if (bitbang_interface->write(1, tms, 0) != ERROR_OK)
return ERROR_FAIL;
if (bitbang_interface->write(0, tms, 0) != ERROR_OK)
@@ -319,7 +316,7 @@ int bitbang_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %u cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
bitbang_end_state(cmd->cmd.runtest->end_state);
@@ -343,7 +340,7 @@ int bitbang_execute_queue(struct jtag_command *cmd_queue)
return ERROR_FAIL;
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %s",
+ LOG_DEBUG_IO("pathmove: %u states, end in %s",
cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
if (bitbang_path_move(cmd->cmd.pathmove) != ERROR_OK)
diff --git a/src/jtag/drivers/bitq.c b/src/jtag/drivers/bitq.c
index 2e5cca2..ef870e6 100644
--- a/src/jtag/drivers/bitq.c
+++ b/src/jtag/drivers/bitq.c
@@ -18,8 +18,8 @@ struct bitq_interface *bitq_interface; /* low level bit queue interface */
/* state of input queue */
struct bitq_state {
struct jtag_command *cmd; /* command currently processed */
- int field_idx; /* index of field currently being processed */
- int bit_pos; /* position of bit currently being processed */
+ unsigned int field_idx; /* index of field currently being processed */
+ unsigned int bit_pos; /* position of bit currently being processed */
int status; /* processing status */
};
static struct bitq_state bitq_in_state;
@@ -108,9 +108,7 @@ static void bitq_state_move(tap_state_t new_state)
static void bitq_path_move(struct pathmove_command *cmd)
{
- int i;
-
- for (i = 0; i < cmd->num_states; i++) {
+ for (unsigned int i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
bitq_io(0, 0, 0);
else if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
@@ -127,16 +125,14 @@ static void bitq_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void bitq_runtest(int num_cycles)
+static void bitq_runtest(unsigned int num_cycles)
{
- int i;
-
/* only do a state_move when we're not already in IDLE */
if (tap_get_state() != TAP_IDLE)
bitq_state_move(TAP_IDLE);
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
bitq_io(0, 0, 0);
/* finish in end_state */
@@ -146,11 +142,10 @@ static void bitq_runtest(int num_cycles)
static void bitq_scan_field(struct scan_field *field, int do_pause)
{
- int bit_cnt;
int tdo_req;
const uint8_t *out_ptr;
- uint8_t out_mask;
+ uint8_t out_mask;
if (field->in_value)
tdo_req = 1;
@@ -159,7 +154,7 @@ static void bitq_scan_field(struct scan_field *field, int do_pause)
if (!field->out_value) {
/* just send zeros and request data from TDO */
- for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)
+ for (unsigned int i = 0; i < (field->num_bits - 1); i++)
bitq_io(0, 0, tdo_req);
bitq_io(do_pause, 0, tdo_req);
@@ -167,7 +162,7 @@ static void bitq_scan_field(struct scan_field *field, int do_pause)
/* send data, and optionally request TDO */
out_mask = 0x01;
out_ptr = field->out_value;
- for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--) {
+ for (unsigned int i = 0; i < (field->num_bits - 1); i++) {
bitq_io(0, ((*out_ptr) & out_mask) != 0, tdo_req);
if (out_mask == 0x80) {
out_mask = 0x01;
@@ -190,13 +185,12 @@ static void bitq_scan_field(struct scan_field *field, int do_pause)
static void bitq_scan(struct scan_command *cmd)
{
- int i;
-
if (cmd->ir_scan)
bitq_state_move(TAP_IRSHIFT);
else
bitq_state_move(TAP_DRSHIFT);
+ unsigned int i;
for (i = 0; i < cmd->num_fields - 1; i++)
bitq_scan_field(&cmd->fields[i], 0);
@@ -226,7 +220,7 @@ int bitq_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
+ LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
bitq_end_state(cmd->cmd.runtest->end_state);
bitq_runtest(cmd->cmd.runtest->num_cycles);
break;
@@ -238,7 +232,7 @@ int bitq_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states,
+ LOG_DEBUG_IO("pathmove: %u states, end in %i", cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
bitq_path_move(cmd->cmd.pathmove);
break;
diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c
index 3b03337..b01a796 100644
--- a/src/jtag/drivers/buspirate.c
+++ b/src/jtag/drivers/buspirate.c
@@ -27,11 +27,11 @@ static int buspirate_reset(int trst, int srst);
static void buspirate_end_state(tap_state_t state);
static void buspirate_state_move(void);
-static void buspirate_path_move(int num_states, tap_state_t *path);
-static void buspirate_runtest(int num_cycles);
+static void buspirate_path_move(unsigned int num_states, tap_state_t *path);
+static void buspirate_runtest(unsigned int num_cycles);
static void buspirate_scan(bool ir_scan, enum scan_type type,
uint8_t *buffer, int scan_size, struct scan_command *command);
-static void buspirate_stableclocks(int num_cycles);
+static void buspirate_stableclocks(unsigned int num_cycles);
#define CMD_UNKNOWN 0x00
#define CMD_PORT_MODE 0x01
@@ -162,7 +162,7 @@ static int buspirate_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %u cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest
->end_state));
@@ -180,7 +180,7 @@ static int buspirate_execute_queue(struct jtag_command *cmd_queue)
buspirate_state_move();
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %s",
+ LOG_DEBUG_IO("pathmove: %u states, end in %s",
cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove
->path[cmd->cmd.pathmove
@@ -210,7 +210,7 @@ static int buspirate_execute_queue(struct jtag_command *cmd_queue)
jtag_sleep(cmd->cmd.sleep->us);
break;
case JTAG_STABLECLOCKS:
- LOG_DEBUG_IO("stable clock %i cycles", cmd->cmd.stableclocks->num_cycles);
+ LOG_DEBUG_IO("stable clock %u cycles", cmd->cmd.stableclocks->num_cycles);
buspirate_stableclocks(cmd->cmd.stableclocks->num_cycles);
break;
default:
@@ -580,11 +580,9 @@ static void buspirate_state_move(void)
tap_set_state(tap_get_end_state());
}
-static void buspirate_path_move(int num_states, tap_state_t *path)
+static void buspirate_path_move(unsigned int num_states, tap_state_t *path)
{
- int i;
-
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (tap_state_transition(tap_get_state(), false) == path[i]) {
buspirate_tap_append(0, 0);
} else if (tap_state_transition(tap_get_state(), true)
@@ -604,10 +602,8 @@ static void buspirate_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-static void buspirate_runtest(int num_cycles)
+static void buspirate_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in IDLE */
@@ -616,7 +612,7 @@ static void buspirate_runtest(int num_cycles)
buspirate_state_move();
}
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
buspirate_tap_append(0, 0);
LOG_DEBUG_IO("runtest: cur_state %s end_state %s",
@@ -658,14 +654,13 @@ static void buspirate_scan(bool ir_scan, enum scan_type type,
buspirate_state_move();
}
-static void buspirate_stableclocks(int num_cycles)
+static void buspirate_stableclocks(unsigned int num_cycles)
{
- int i;
int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
buspirate_tap_make_space(0, num_cycles);
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
buspirate_tap_append(tms, 0);
}
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index d7367d8..a6dcfcd 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -1752,7 +1752,7 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd)
LOG_DEBUG("discarding trailing empty field");
}
- if (cmd->cmd.scan->num_fields == 0) {
+ if (!cmd->cmd.scan->num_fields) {
LOG_DEBUG("empty scan, doing nothing");
return;
}
@@ -1772,11 +1772,11 @@ static void cmsis_dap_execute_scan(struct jtag_command *cmd)
cmsis_dap_end_state(cmd->cmd.scan->end_state);
struct scan_field *field = cmd->cmd.scan->fields;
- unsigned scan_size = 0;
+ unsigned int scan_size = 0;
- for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
scan_size += field->num_bits;
- LOG_DEBUG_IO("%s%s field %d/%d %d bits",
+ LOG_DEBUG_IO("%s%s field %u/%u %u bits",
field->in_value ? "in" : "",
field->out_value ? "out" : "",
i,
@@ -1872,16 +1872,16 @@ static void cmsis_dap_execute_pathmove(struct jtag_command *cmd)
cmsis_dap_pathmove(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);
}
-static void cmsis_dap_stableclocks(int num_cycles)
+static void cmsis_dap_stableclocks(unsigned int num_cycles)
{
uint8_t tms = tap_get_state() == TAP_RESET;
/* TODO: Perform optimizations? */
/* Execute num_cycles. */
- for (int i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
cmsis_dap_add_tms_sequence(&tms, 1);
}
-static void cmsis_dap_runtest(int num_cycles)
+static void cmsis_dap_runtest(unsigned int num_cycles)
{
tap_state_t saved_end_state = tap_get_end_state();
@@ -1901,7 +1901,7 @@ static void cmsis_dap_runtest(int num_cycles)
static void cmsis_dap_execute_runtest(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
+ LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
cmsis_dap_end_state(cmd->cmd.runtest->end_state);
@@ -1910,13 +1910,13 @@ static void cmsis_dap_execute_runtest(struct jtag_command *cmd)
static void cmsis_dap_execute_stableclocks(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("stableclocks %i cycles", cmd->cmd.runtest->num_cycles);
+ LOG_DEBUG_IO("stableclocks %u cycles", cmd->cmd.runtest->num_cycles);
cmsis_dap_stableclocks(cmd->cmd.runtest->num_cycles);
}
static void cmsis_dap_execute_tms(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
+ LOG_DEBUG_IO("TMS: %u bits", cmd->cmd.tms->num_bits);
cmsis_dap_cmd_dap_swj_sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);
}
diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c
index e52816d..2aad4a0 100644
--- a/src/jtag/drivers/driver.c
+++ b/src/jtag/drivers/driver.c
@@ -259,7 +259,7 @@ int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state
return ERROR_OK;
}
-int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
+int interface_jtag_add_pathmove(unsigned int num_states, const tap_state_t *path)
{
/* allocate memory for a new list member */
struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
@@ -272,13 +272,13 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path)
cmd->cmd.pathmove->num_states = num_states;
cmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states);
- for (int i = 0; i < num_states; i++)
+ for (unsigned int i = 0; i < num_states; i++)
cmd->cmd.pathmove->path[i] = path[i];
return ERROR_OK;
}
-int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
+int interface_jtag_add_runtest(unsigned int num_cycles, tap_state_t state)
{
/* allocate memory for a new list member */
struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
@@ -294,7 +294,7 @@ int interface_jtag_add_runtest(int num_cycles, tap_state_t state)
return ERROR_OK;
}
-int interface_jtag_add_clocks(int num_cycles)
+int interface_jtag_add_clocks(unsigned int num_cycles)
{
/* allocate memory for a new list member */
struct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));
diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c
index 766f6dd..a4d072c 100644
--- a/src/jtag/drivers/ft232r.c
+++ b/src/jtag/drivers/ft232r.c
@@ -657,7 +657,7 @@ static int syncbb_execute_tms(struct jtag_command *cmd)
unsigned num_bits = cmd->cmd.tms->num_bits;
const uint8_t *bits = cmd->cmd.tms->bits;
- LOG_DEBUG_IO("TMS: %d bits", num_bits);
+ LOG_DEBUG_IO("TMS: %u bits", num_bits);
int tms = 0;
for (unsigned i = 0; i < num_bits; i++) {
@@ -672,7 +672,7 @@ static int syncbb_execute_tms(struct jtag_command *cmd)
static void syncbb_path_move(struct pathmove_command *cmd)
{
- int num_states = cmd->num_states;
+ unsigned int num_states = cmd->num_states;
int state_count;
int tms = 0;
@@ -702,9 +702,8 @@ static void syncbb_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void syncbb_runtest(int num_cycles)
+static void syncbb_runtest(unsigned int num_cycles)
{
- int i;
tap_state_t saved_end_state = tap_get_end_state();
@@ -715,7 +714,7 @@ static void syncbb_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
ft232r_write(0, 0, 0);
ft232r_write(1, 0, 0);
}
@@ -735,13 +734,12 @@ static void syncbb_runtest(int num_cycles)
* this function checks the current stable state to decide on the value of TMS
* to use.
*/
-static void syncbb_stableclocks(int num_cycles)
+static void syncbb_stableclocks(unsigned int num_cycles)
{
int tms = (tap_get_state() == TAP_RESET ? 1 : 0);
- int i;
/* send num_cycles clocks onto the cable */
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
ft232r_write(1, tms, 0);
ft232r_write(0, tms, 0);
}
@@ -832,7 +830,7 @@ static int syncbb_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles,
+ LOG_DEBUG_IO("runtest %u cycles, end in %s", cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
syncbb_end_state(cmd->cmd.runtest->end_state);
@@ -854,7 +852,7 @@ static int syncbb_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %s", cmd->cmd.pathmove->num_states,
+ LOG_DEBUG_IO("pathmove: %u states, end in %s", cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
syncbb_path_move(cmd->cmd.pathmove);
diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c
index 1793cbf..66d0d50 100644
--- a/src/jtag/drivers/ftdi.c
+++ b/src/jtag/drivers/ftdi.c
@@ -383,10 +383,9 @@ static void ftdi_end_state(tap_state_t state)
static void ftdi_execute_runtest(struct jtag_command *cmd)
{
- int i;
- static const uint8_t zero;
+ uint8_t zero = 0;
- LOG_DEBUG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %u cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
@@ -394,7 +393,7 @@ static void ftdi_execute_runtest(struct jtag_command *cmd)
move_to_state(TAP_IDLE);
/* TODO: Reuse ftdi_execute_stableclocks */
- i = cmd->cmd.runtest->num_cycles;
+ unsigned int i = cmd->cmd.runtest->num_cycles;
while (i > 0) {
/* there are no state transitions in this code, so omit state tracking */
unsigned this_len = i > 7 ? 7 : i;
@@ -407,7 +406,7 @@ static void ftdi_execute_runtest(struct jtag_command *cmd)
if (tap_get_state() != tap_get_end_state())
move_to_state(tap_get_end_state());
- LOG_DEBUG_IO("runtest: %i, end in %s",
+ LOG_DEBUG_IO("runtest: %u, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(tap_get_end_state()));
}
@@ -430,7 +429,7 @@ static void ftdi_execute_statemove(struct jtag_command *cmd)
*/
static void ftdi_execute_tms(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("TMS: %d bits", cmd->cmd.tms->num_bits);
+ LOG_DEBUG_IO("TMS: %u bits", cmd->cmd.tms->num_bits);
/* TODO: Missing tap state tracking, also missing from ft2232.c! */
DO_CLOCK_TMS_CS_OUT(mpsse_ctx,
@@ -444,9 +443,9 @@ static void ftdi_execute_tms(struct jtag_command *cmd)
static void ftdi_execute_pathmove(struct jtag_command *cmd)
{
tap_state_t *path = cmd->cmd.pathmove->path;
- int num_states = cmd->cmd.pathmove->num_states;
+ unsigned int num_states = cmd->cmd.pathmove->num_states;
- LOG_DEBUG_IO("pathmove: %i states, current: %s end: %s", num_states,
+ LOG_DEBUG_IO("pathmove: %u states, current: %s end: %s", num_states,
tap_state_name(tap_get_state()),
tap_state_name(path[num_states-1]));
@@ -504,7 +503,7 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
LOG_DEBUG_IO("discarding trailing empty field");
}
- if (cmd->cmd.scan->num_fields == 0) {
+ if (!cmd->cmd.scan->num_fields) {
LOG_DEBUG_IO("empty scan, doing nothing");
return;
}
@@ -522,9 +521,9 @@ static void ftdi_execute_scan(struct jtag_command *cmd)
struct scan_field *field = cmd->cmd.scan->fields;
unsigned scan_size = 0;
- for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
scan_size += field->num_bits;
- LOG_DEBUG_IO("%s%s field %d/%d %d bits",
+ LOG_DEBUG_IO("%s%s field %u/%u %u bits",
field->in_value ? "in" : "",
field->out_value ? "out" : "",
i,
@@ -644,7 +643,7 @@ static void ftdi_execute_stableclocks(struct jtag_command *cmd)
/* this is only allowed while in a stable state. A check for a stable
* state was done in jtag_add_clocks()
*/
- int num_cycles = cmd->cmd.stableclocks->num_cycles;
+ unsigned int num_cycles = cmd->cmd.stableclocks->num_cycles;
/* 7 bits of either ones or zeros. */
uint8_t tms = tap_get_state() == TAP_RESET ? 0x7f : 0x00;
@@ -658,7 +657,7 @@ static void ftdi_execute_stableclocks(struct jtag_command *cmd)
num_cycles -= this_len;
}
- LOG_DEBUG_IO("clocks %i while in %s",
+ LOG_DEBUG_IO("clocks %u while in %s",
cmd->cmd.stableclocks->num_cycles,
tap_state_name(tap_get_state()));
}
diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c
index a4c6fd0..d0fe43f 100644
--- a/src/jtag/drivers/gw16012.c
+++ b/src/jtag/drivers/gw16012.c
@@ -185,10 +185,9 @@ static void gw16012_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void gw16012_runtest(int num_cycles)
+static void gw16012_runtest(unsigned int num_cycles)
{
tap_state_t saved_end_state = tap_get_end_state();
- int i;
/* only do a state_move when we're not already in IDLE */
if (tap_get_state() != TAP_IDLE) {
@@ -196,7 +195,7 @@ static void gw16012_runtest(int num_cycles)
gw16012_state_move();
}
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
gw16012_control(0x0); /* single-bit mode */
gw16012_data(0x0); /* TMS cycle with TMS low */
}
@@ -292,7 +291,7 @@ static int gw16012_execute_queue(struct jtag_command *cmd_queue)
gw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
break;
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
+ LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
gw16012_end_state(cmd->cmd.runtest->end_state);
gw16012_runtest(cmd->cmd.runtest->num_cycles);
diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index 1874557..a94f3a4 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -80,9 +80,9 @@ static struct device_config tmp_config;
/* Queue command functions */
static void jlink_end_state(tap_state_t state);
static void jlink_state_move(void);
-static void jlink_path_move(int num_states, tap_state_t *path);
-static void jlink_stableclocks(int num_cycles);
-static void jlink_runtest(int num_cycles);
+static void jlink_path_move(unsigned int num_states, tap_state_t *path);
+static void jlink_stableclocks(unsigned int num_cycles);
+static void jlink_runtest(unsigned int num_cycles);
static void jlink_reset(int trst, int srst);
static int jlink_reset_safe(int trst, int srst);
static int jlink_swd_run_queue(void);
@@ -140,7 +140,7 @@ static void jlink_execute_statemove(struct jtag_command *cmd)
static void jlink_execute_pathmove(struct jtag_command *cmd)
{
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
@@ -159,7 +159,7 @@ static void jlink_execute_scan(struct jtag_command *cmd)
LOG_DEBUG("discarding trailing empty field");
}
- if (cmd->cmd.scan->num_fields == 0) {
+ if (!cmd->cmd.scan->num_fields) {
LOG_DEBUG("empty scan, doing nothing");
return;
}
@@ -181,9 +181,9 @@ static void jlink_execute_scan(struct jtag_command *cmd)
struct scan_field *field = cmd->cmd.scan->fields;
unsigned scan_size = 0;
- for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
scan_size += field->num_bits;
- LOG_DEBUG_IO("%s%s field %d/%d %d bits",
+ LOG_DEBUG_IO("%s%s field %u/%u %u bits",
field->in_value ? "in" : "",
field->out_value ? "out" : "",
i,
@@ -885,12 +885,11 @@ static void jlink_state_move(void)
tap_set_state(tap_get_end_state());
}
-static void jlink_path_move(int num_states, tap_state_t *path)
+static void jlink_path_move(unsigned int num_states, tap_state_t *path)
{
- int i;
uint8_t tms = 0xff;
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false))
jlink_clock_data(NULL, 0, NULL, 0, NULL, 0, 1);
else if (path[i] == tap_state_transition(tap_get_state(), true))
@@ -907,17 +906,15 @@ static void jlink_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-static void jlink_stableclocks(int num_cycles)
+static void jlink_stableclocks(unsigned int num_cycles)
{
- int i;
-
uint8_t tms = tap_get_state() == TAP_RESET;
/* Execute num_cycles. */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
jlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1);
}
-static void jlink_runtest(int num_cycles)
+static void jlink_runtest(unsigned int num_cycles)
{
tap_state_t saved_end_state = tap_get_end_state();
@@ -964,23 +961,18 @@ static int jlink_reset_safe(int trst, int srst)
COMMAND_HANDLER(jlink_usb_command)
{
- int tmp;
-
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) {
- command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
- return ERROR_COMMAND_ARGUMENT_INVALID;
- }
+ unsigned int tmp;
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], tmp);
- if (tmp < JAYLINK_USB_ADDRESS_0 || tmp > JAYLINK_USB_ADDRESS_3) {
+ if (tmp > JAYLINK_USB_ADDRESS_3) {
command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
usb_address = tmp;
-
use_usb_address = true;
return ERROR_OK;
@@ -1038,38 +1030,35 @@ COMMAND_HANDLER(jlink_handle_free_memory_command)
COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
{
- int tmp;
- int version;
-
if (!CMD_ARGC) {
+ unsigned int version;
+
switch (jtag_command_version) {
- case JAYLINK_JTAG_VERSION_2:
- version = 2;
- break;
- case JAYLINK_JTAG_VERSION_3:
- version = 3;
- break;
- default:
- return ERROR_FAIL;
+ case JAYLINK_JTAG_VERSION_2:
+ version = 2;
+ break;
+ case JAYLINK_JTAG_VERSION_3:
+ version = 3;
+ break;
+ default:
+ return ERROR_FAIL;
}
- command_print(CMD, "JTAG command version: %i", version);
+ command_print(CMD, "JTAG command version: %u", version);
} else if (CMD_ARGC == 1) {
- if (sscanf(CMD_ARGV[0], "%i", &tmp) != 1) {
- command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
- return ERROR_COMMAND_ARGUMENT_INVALID;
- }
+ uint8_t tmp;
+ COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], tmp);
switch (tmp) {
- case 2:
- jtag_command_version = JAYLINK_JTAG_VERSION_2;
- break;
- case 3:
- jtag_command_version = JAYLINK_JTAG_VERSION_3;
- break;
- default:
- command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
- return ERROR_COMMAND_ARGUMENT_INVALID;
+ case 2:
+ jtag_command_version = JAYLINK_JTAG_VERSION_2;
+ break;
+ case 3:
+ jtag_command_version = JAYLINK_JTAG_VERSION_3;
+ break;
+ default:
+ command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
+ return ERROR_COMMAND_ARGUMENT_INVALID;
}
} else {
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1080,10 +1069,7 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
COMMAND_HANDLER(jlink_handle_target_power_command)
{
- int ret;
- int enable;
-
- if (CMD_ARGC != 1)
+ if (CMD_ARGC > 1)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) {
@@ -1092,16 +1078,24 @@ COMMAND_HANDLER(jlink_handle_target_power_command)
return ERROR_OK;
}
- if (!strcmp(CMD_ARGV[0], "on")) {
- enable = true;
- } else if (!strcmp(CMD_ARGV[0], "off")) {
- enable = false;
- } else {
- command_print(CMD, "Invalid argument: %s", CMD_ARGV[0]);
- return ERROR_FAIL;
+ if (!CMD_ARGC) {
+ uint32_t state;
+ int ret = jaylink_get_hardware_info(devh, JAYLINK_HW_INFO_TARGET_POWER,
+ &state);
+
+ if (ret != JAYLINK_OK) {
+ command_print(CMD, "Failed to retrieve target power state");
+ return ERROR_FAIL;
+ }
+
+ command_print(CMD, "%d", (bool)state);
+ return ERROR_OK;
}
- ret = jaylink_set_target_power(devh, enable);
+ bool enable;
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);
+
+ int ret = jaylink_set_target_power(devh, enable);
if (ret != JAYLINK_OK) {
command_print(CMD, "jaylink_set_target_power() failed: %s",
@@ -1410,8 +1404,6 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
COMMAND_HANDLER(jlink_handle_config_usb_address_command)
{
- uint8_t tmp;
-
if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {
command_print(CMD, "Reading configuration is not supported by the "
"device");
@@ -1421,10 +1413,8 @@ COMMAND_HANDLER(jlink_handle_config_usb_address_command)
if (!CMD_ARGC) {
show_config_usb_address(CMD);
} else if (CMD_ARGC == 1) {
- if (sscanf(CMD_ARGV[0], "%" SCNd8, &tmp) != 1) {
- command_print(CMD, "Invalid USB address: %s", CMD_ARGV[0]);
- return ERROR_COMMAND_ARGUMENT_INVALID;
- }
+ uint8_t tmp;
+ COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], tmp);
if (tmp > JAYLINK_USB_ADDRESS_3) {
command_print(CMD, "Invalid USB address: %u", tmp);
@@ -1883,7 +1873,7 @@ static const struct command_registration jlink_subcommand_handlers[] = {
.handler = &jlink_handle_target_power_command,
.mode = COMMAND_EXEC,
.help = "set the target power supply",
- .usage = "<on|off>"
+ .usage = "[0|1|on|off]"
},
{
.name = "freemem",
diff --git a/src/jtag/drivers/jtag_dpi.c b/src/jtag/drivers/jtag_dpi.c
index 285f96e..046186a 100644
--- a/src/jtag/drivers/jtag_dpi.c
+++ b/src/jtag/drivers/jtag_dpi.c
@@ -163,7 +163,7 @@ out:
return ret;
}
-static int jtag_dpi_runtest(int cycles)
+static int jtag_dpi_runtest(unsigned int num_cycles)
{
char buf[20];
uint8_t *data_buf = last_ir_buf, *read_scan;
@@ -189,7 +189,7 @@ static int jtag_dpi_runtest(int cycles)
return ERROR_FAIL;
}
snprintf(buf, sizeof(buf), "ib %d\n", num_bits);
- while (cycles > 0) {
+ while (num_cycles > 0) {
ret = write_sock(buf, strlen(buf));
if (ret != ERROR_OK) {
LOG_ERROR("write_sock() fail, file %s, line %d",
@@ -209,7 +209,7 @@ static int jtag_dpi_runtest(int cycles)
goto out;
}
- cycles -= num_bits + 6;
+ num_cycles -= num_bits + 6;
}
out:
@@ -217,9 +217,9 @@ out:
return ret;
}
-static int jtag_dpi_stableclocks(int cycles)
+static int jtag_dpi_stableclocks(unsigned int num_cycles)
{
- return jtag_dpi_runtest(cycles);
+ return jtag_dpi_runtest(num_cycles);
}
static int jtag_dpi_execute_queue(struct jtag_command *cmd_queue)
diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c
index 9dec0d1..a19060c 100644
--- a/src/jtag/drivers/jtag_vpi.c
+++ b/src/jtag/drivers/jtag_vpi.c
@@ -254,7 +254,7 @@ static int jtag_vpi_path_move(struct pathmove_command *cmd)
memset(trans, 0, DIV_ROUND_UP(cmd->num_states, 8));
- for (int i = 0; i < cmd->num_states; i++) {
+ for (unsigned int i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
buf_set_u32(trans, i, 1, 1);
tap_set_state(cmd->path[i]);
@@ -440,7 +440,7 @@ static int jtag_vpi_scan(struct scan_command *cmd)
return ERROR_OK;
}
-static int jtag_vpi_runtest(int cycles, tap_state_t state)
+static int jtag_vpi_runtest(unsigned int num_cycles, tap_state_t state)
{
int retval;
@@ -448,22 +448,20 @@ static int jtag_vpi_runtest(int cycles, tap_state_t state)
if (retval != ERROR_OK)
return retval;
- retval = jtag_vpi_queue_tdi(NULL, cycles, NO_TAP_SHIFT);
+ retval = jtag_vpi_queue_tdi(NULL, num_cycles, NO_TAP_SHIFT);
if (retval != ERROR_OK)
return retval;
return jtag_vpi_state_move(state);
}
-static int jtag_vpi_stableclocks(int cycles)
+static int jtag_vpi_stableclocks(unsigned int num_cycles)
{
uint8_t tms_bits[4];
- int cycles_remain = cycles;
+ unsigned int cycles_remain = num_cycles;
int nb_bits;
int retval;
- const int CYCLES_ONE_BATCH = sizeof(tms_bits) * 8;
-
- assert(cycles >= 0);
+ const unsigned int CYCLES_ONE_BATCH = sizeof(tms_bits) * 8;
/* use TMS=1 in TAP RESET state, TMS=0 in all other stable states */
memset(&tms_bits, (tap_get_state() == TAP_RESET) ? 0xff : 0x00, sizeof(tms_bits));
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c
index f3499e3..3decddb 100644
--- a/src/jtag/drivers/mpsse.c
+++ b/src/jtag/drivers/mpsse.c
@@ -283,6 +283,9 @@ static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t vids[], c
case 0x3300:
ctx->type = TYPE_FT232HP;
break;
+ case 0x3600:
+ ctx->type = TYPE_FT4232HA;
+ break;
default:
LOG_ERROR("unsupported FTDI chip type: 0x%04x", desc.bcdDevice);
goto error;
diff --git a/src/jtag/drivers/mpsse.h b/src/jtag/drivers/mpsse.h
index e92a9bb..737560d 100644
--- a/src/jtag/drivers/mpsse.h
+++ b/src/jtag/drivers/mpsse.h
@@ -30,6 +30,7 @@ enum ftdi_chip_type {
TYPE_FT4232HP,
TYPE_FT233HP,
TYPE_FT232HP,
+ TYPE_FT4232HA,
};
struct mpsse_ctx;
diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c
index 81b74d4..e828d46 100644
--- a/src/jtag/drivers/opendous.c
+++ b/src/jtag/drivers/opendous.c
@@ -106,8 +106,8 @@ static int opendous_quit(void);
/* Queue command functions */
static void opendous_end_state(tap_state_t state);
static void opendous_state_move(void);
-static void opendous_path_move(int num_states, tap_state_t *path);
-static void opendous_runtest(int num_cycles);
+static void opendous_path_move(unsigned int num_states, tap_state_t *path);
+static void opendous_runtest(unsigned int num_cycles);
static void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer,
int scan_size, struct scan_command *command);
static void opendous_reset(int trst, int srst);
@@ -248,7 +248,7 @@ static int opendous_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles,
+ LOG_DEBUG_IO("runtest %u cycles, end in %i", cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
if (cmd->cmd.runtest->end_state != -1)
@@ -265,7 +265,7 @@ static int opendous_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
@@ -419,11 +419,9 @@ void opendous_state_move(void)
tap_set_state(tap_get_end_state());
}
-void opendous_path_move(int num_states, tap_state_t *path)
+void opendous_path_move(unsigned int num_states, tap_state_t *path)
{
- int i;
-
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false))
opendous_tap_append_step(0, 0);
else if (path[i] == tap_state_transition(tap_get_state(), true))
@@ -440,10 +438,8 @@ void opendous_path_move(int num_states, tap_state_t *path)
tap_set_end_state(tap_get_state());
}
-void opendous_runtest(int num_cycles)
+void opendous_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in IDLE */
@@ -453,7 +449,7 @@ void opendous_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
opendous_tap_append_step(0, 0);
/* finish in end_state */
diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c
index ea78ca8..0ae885e 100644
--- a/src/jtag/drivers/openjtag.c
+++ b/src/jtag/drivers/openjtag.c
@@ -760,15 +760,17 @@ static void openjtag_execute_runtest(struct jtag_command *cmd)
if (openjtag_variant != OPENJTAG_VARIANT_CY7C65215 ||
cmd->cmd.runtest->num_cycles) {
uint8_t command;
- int cycles = cmd->cmd.runtest->num_cycles;
+ unsigned int num_cycles = cmd->cmd.runtest->num_cycles;
do {
+ const unsigned int num_cycles_cmd = MIN(num_cycles, 16);
+
command = 7;
- command |= (((cycles > 16 ? 16 : cycles) - 1) & 0x0F) << 4;
+ command |= ((num_cycles_cmd - 1) & 0x0F) << 4;
openjtag_add_byte(command);
- cycles -= 16;
- } while (cycles > 0);
+ num_cycles -= num_cycles_cmd;
+ } while (num_cycles > 0);
}
tap_set_end_state(end_state);
diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c
index 8d4fc90..c41a0e1 100644
--- a/src/jtag/drivers/osbdm.c
+++ b/src/jtag/drivers/osbdm.c
@@ -381,7 +381,7 @@ static int osbdm_quit(void)
static int osbdm_add_pathmove(
struct queue *queue,
tap_state_t *path,
- int num_states)
+ unsigned int num_states)
{
assert(num_states <= 32);
@@ -392,7 +392,7 @@ static int osbdm_add_pathmove(
}
uint32_t tms = 0;
- for (int i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (tap_state_transition(tap_get_state(), 1) == path[i]) {
tms |= (1 << i);
} else if (tap_state_transition(tap_get_state(), 0) == path[i]) {
@@ -451,7 +451,7 @@ static int osbdm_add_statemove(
static int osbdm_add_stableclocks(
struct queue *queue,
- int count)
+ unsigned int count)
{
if (!tap_is_state_stable(tap_get_state())) {
LOG_ERROR("BUG: current state (%s) is not stable",
@@ -489,7 +489,7 @@ static int osbdm_add_tms(
static int osbdm_add_scan(
struct queue *queue,
struct scan_field *fields,
- int num_fields,
+ unsigned int num_fields,
tap_state_t end_state,
bool ir_scan)
{
@@ -508,7 +508,7 @@ static int osbdm_add_scan(
/* Add scan */
tap_set_end_state(end_state);
- for (int idx = 0; idx < num_fields; idx++) {
+ for (unsigned int idx = 0; idx < num_fields; idx++) {
struct sequence *next = queue_add_tail(queue, fields[idx].num_bits);
if (!next) {
LOG_ERROR("Can't allocate bit sequence");
@@ -536,7 +536,7 @@ static int osbdm_add_scan(
static int osbdm_add_runtest(
struct queue *queue,
- int num_cycles,
+ unsigned int num_cycles,
tap_state_t end_state)
{
if (osbdm_add_statemove(queue, TAP_IDLE, 0) != ERROR_OK)
diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c
index afdf16e..f4a4fcb 100644
--- a/src/jtag/drivers/rlink.c
+++ b/src/jtag/drivers/rlink.c
@@ -869,7 +869,7 @@ static void rlink_state_move(void)
static void rlink_path_move(struct pathmove_command *cmd)
{
- int num_states = cmd->num_states;
+ unsigned int num_states = cmd->num_states;
int state_count;
int tms = 0;
@@ -896,10 +896,8 @@ static void rlink_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void rlink_runtest(int num_cycles)
+static void rlink_runtest(unsigned int num_cycles)
{
- int i;
-
tap_state_t saved_end_state = tap_get_end_state();
/* only do a state_move when we're not already in RTI */
@@ -909,7 +907,7 @@ static void rlink_runtest(int num_cycles)
}
/* execute num_cycles */
- for (i = 0; i < num_cycles; i++)
+ for (unsigned int i = 0; i < num_cycles; i++)
tap_state_queue_append(0);
/* finish in end_state */
@@ -1323,7 +1321,7 @@ static int rlink_execute_queue(struct jtag_command *cmd_queue)
rlink_state_move();
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
rlink_path_move(cmd->cmd.pathmove);
diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c
index 0fe8989..ad3bc6e 100644
--- a/src/jtag/drivers/ulink.c
+++ b/src/jtag/drivers/ulink.c
@@ -1701,15 +1701,17 @@ static int ulink_queue_reset(struct ulink *device, struct jtag_command *cmd)
*/
static int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd)
{
- int ret, i, num_states, batch_size, state_count;
+ int ret, state_count;
tap_state_t *path;
uint8_t tms_sequence;
- num_states = cmd->cmd.pathmove->num_states;
+ unsigned int num_states = cmd->cmd.pathmove->num_states;
path = cmd->cmd.pathmove->path;
state_count = 0;
while (num_states > 0) {
+ unsigned int batch_size;
+
tms_sequence = 0;
/* Determine batch size */
@@ -1718,7 +1720,7 @@ static int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd)
else
batch_size = num_states;
- for (i = 0; i < batch_size; i++) {
+ for (unsigned int i = 0; i < batch_size; i++) {
if (tap_state_transition(tap_get_state(), false) == path[state_count]) {
/* Append '0' transition: clear bit 'i' in tms_sequence */
buf_set_u32(&tms_sequence, i, 1, 0x0);
@@ -1774,14 +1776,13 @@ static int ulink_queue_sleep(struct ulink *device, struct jtag_command *cmd)
static int ulink_queue_stableclocks(struct ulink *device, struct jtag_command *cmd)
{
int ret;
- unsigned num_cycles;
if (!tap_is_state_stable(tap_get_state())) {
LOG_ERROR("JTAG_STABLECLOCKS: state not stable");
return ERROR_FAIL;
}
- num_cycles = cmd->cmd.stableclocks->num_cycles;
+ unsigned int num_cycles = cmd->cmd.stableclocks->num_cycles;
/* TMS stays either high (Test Logic Reset state) or low (all other states) */
if (tap_get_state() == TAP_RESET)
diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c
index c84055c..53dd158 100644
--- a/src/jtag/drivers/usb_blaster/usb_blaster.c
+++ b/src/jtag/drivers/usb_blaster/usb_blaster.c
@@ -474,11 +474,9 @@ static void ublast_tms(struct tms_command *cmd)
*/
static void ublast_path_move(struct pathmove_command *cmd)
{
- int i;
-
- LOG_DEBUG_IO("(num_states=%d, last_state=%d)",
+ LOG_DEBUG_IO("(num_states=%u, last_state=%d)",
cmd->num_states, cmd->path[cmd->num_states - 1]);
- for (i = 0; i < cmd->num_states; i++) {
+ for (unsigned int i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
ublast_clock_tms(0);
if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
@@ -675,19 +673,19 @@ static void ublast_queue_tdi(uint8_t *bits, int nb_bits, enum scan_type scan)
ublast_idle_clock();
}
-static void ublast_runtest(int cycles, tap_state_t state)
+static void ublast_runtest(unsigned int num_cycles, tap_state_t state)
{
- LOG_DEBUG_IO("%s(cycles=%i, end_state=%d)", __func__, cycles, state);
+ LOG_DEBUG_IO("%s(cycles=%u, end_state=%d)", __func__, num_cycles, state);
ublast_state_move(TAP_IDLE, 0);
- ublast_queue_tdi(NULL, cycles, SCAN_OUT);
+ ublast_queue_tdi(NULL, num_cycles, SCAN_OUT);
ublast_state_move(state, 0);
}
-static void ublast_stableclocks(int cycles)
+static void ublast_stableclocks(unsigned int num_cycles)
{
- LOG_DEBUG_IO("%s(cycles=%i)", __func__, cycles);
- ublast_queue_tdi(NULL, cycles, SCAN_OUT);
+ LOG_DEBUG_IO("%s(cycles=%u)", __func__, num_cycles);
+ ublast_queue_tdi(NULL, num_cycles, SCAN_OUT);
}
/**
diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c
index 2d666d0..6e3b3ba 100644
--- a/src/jtag/drivers/usbprog.c
+++ b/src/jtag/drivers/usbprog.c
@@ -37,7 +37,7 @@
static void usbprog_end_state(tap_state_t state);
static void usbprog_state_move(void);
static void usbprog_path_move(struct pathmove_command *cmd);
-static void usbprog_runtest(int num_cycles);
+static void usbprog_runtest(unsigned int num_cycles);
static void usbprog_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size);
#define UNKNOWN_COMMAND 0x00
@@ -101,7 +101,7 @@ static int usbprog_execute_queue(struct jtag_command *cmd_queue)
usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
break;
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %i",
+ LOG_DEBUG_IO("runtest %u cycles, end in %i",
cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
usbprog_end_state(cmd->cmd.runtest->end_state);
@@ -113,7 +113,7 @@ static int usbprog_execute_queue(struct jtag_command *cmd_queue)
usbprog_state_move();
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %i",
+ LOG_DEBUG_IO("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
usbprog_path_move(cmd->cmd.pathmove);
@@ -189,7 +189,7 @@ static void usbprog_state_move(void)
static void usbprog_path_move(struct pathmove_command *cmd)
{
- int num_states = cmd->num_states;
+ unsigned int num_states = cmd->num_states;
int state_count;
/* There may be queued transitions, and before following a specified
@@ -222,10 +222,8 @@ static void usbprog_path_move(struct pathmove_command *cmd)
tap_set_end_state(tap_get_state());
}
-static void usbprog_runtest(int num_cycles)
+static void usbprog_runtest(unsigned int num_cycles)
{
- int i;
-
/* only do a state_move when we're not already in IDLE */
if (tap_get_state() != TAP_IDLE) {
usbprog_end_state(TAP_IDLE);
@@ -241,7 +239,7 @@ static void usbprog_runtest(int num_cycles)
/* LOG_INFO("NUM CYCLES %i",num_cycles); */
}
- for (i = 0; i < num_cycles; i++) {
+ for (unsigned int i = 0; i < num_cycles; i++) {
usbprog_write(1, 0, 0);
usbprog_write(0, 0, 0);
}
diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c
index f1fc453..691e576 100644
--- a/src/jtag/drivers/vdebug.c
+++ b/src/jtag/drivers/vdebug.c
@@ -931,11 +931,11 @@ static int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush)
static int vdebug_jtag_path_move(struct pathmove_command *cmd, uint8_t f_flush)
{
uint8_t tms[DIV_ROUND_UP(cmd->num_states, 8)];
- LOG_DEBUG_IO("path num states %d", cmd->num_states);
+ LOG_DEBUG_IO("path num states %u", cmd->num_states);
memset(tms, 0, DIV_ROUND_UP(cmd->num_states, 8));
- for (uint8_t i = 0; i < cmd->num_states; i++) {
+ for (unsigned int i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
buf_set_u32(tms, i, 1, 1);
tap_set_state(cmd->path[i]);
@@ -970,10 +970,10 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush)
uint8_t num_pre = tap_get_tms_path_len(cur, state);
uint8_t tms_post = tap_get_tms_path(state, cmd->end_state);
uint8_t num_post = tap_get_tms_path_len(state, cmd->end_state);
- int num_bits = jtag_scan_size(cmd);
- LOG_DEBUG_IO("scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x",
+ const unsigned int num_bits = jtag_scan_size(cmd);
+ LOG_DEBUG_IO("scan len:%u fields:%u ir/!dr:%d state cur:%x end:%x",
num_bits, cmd->num_fields, cmd->ir_scan, cur, cmd->end_state);
- for (int i = 0; i < cmd->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->num_fields; i++) {
uint8_t cur_num_pre = i == 0 ? num_pre : 0;
uint8_t cur_tms_pre = i == 0 ? tms_pre : 0;
uint8_t cur_num_post = i == cmd->num_fields - 1 ? num_post : 0;
@@ -992,24 +992,24 @@ static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush)
return rc;
}
-static int vdebug_jtag_runtest(int cycles, tap_state_t state, uint8_t f_flush)
+static int vdebug_jtag_runtest(unsigned int num_cycles, tap_state_t state, uint8_t f_flush)
{
tap_state_t cur = tap_get_state();
uint8_t tms_pre = tap_get_tms_path(cur, state);
uint8_t num_pre = tap_get_tms_path_len(cur, state);
- LOG_DEBUG_IO("idle len:%d state cur:%x end:%x", cycles, cur, state);
- int rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, cycles, NULL, 0, 0, NULL, f_flush);
+ LOG_DEBUG_IO("idle len:%u state cur:%x end:%x", num_cycles, cur, state);
+ int rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, num_cycles, NULL, 0, 0, NULL, f_flush);
if (cur != state)
tap_set_state(state);
return rc;
}
-static int vdebug_jtag_stableclocks(int num, uint8_t f_flush)
+static int vdebug_jtag_stableclocks(unsigned int num_cycles, uint8_t f_flush)
{
- LOG_DEBUG("stab len:%d state cur:%x", num, tap_get_state());
+ LOG_DEBUG("stab len:%u state cur:%x", num_cycles, tap_get_state());
- return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, 0, 0, num, NULL, 0, 0, NULL, f_flush);
+ return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, 0, 0, num_cycles, NULL, 0, 0, NULL, f_flush);
}
static int vdebug_sleep(int us)
diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c
index 34525d5..ca14217 100644
--- a/src/jtag/drivers/vsllink.c
+++ b/src/jtag/drivers/vsllink.c
@@ -43,10 +43,10 @@ static struct pending_scan_result
/* Queue command functions */
static void vsllink_end_state(tap_state_t state);
static void vsllink_state_move(void);
-static void vsllink_path_move(int num_states, tap_state_t *path);
+static void vsllink_path_move(unsigned int num_states, tap_state_t *path);
static void vsllink_tms(int num_bits, const uint8_t *bits);
-static void vsllink_runtest(int num_cycles);
-static void vsllink_stableclocks(int num_cycles, int tms);
+static void vsllink_runtest(unsigned int num_cycles);
+static void vsllink_stableclocks(unsigned int num_cycles, int tms);
static void vsllink_scan(bool ir_scan, enum scan_type type,
uint8_t *buffer, int scan_size, struct scan_command *command);
static int vsllink_reset(int trst, int srst);
@@ -98,7 +98,7 @@ static int vsllink_execute_queue(struct jtag_command *cmd_queue)
while (cmd) {
switch (cmd->type) {
case JTAG_RUNTEST:
- LOG_DEBUG_IO("runtest %i cycles, end in %s",
+ LOG_DEBUG_IO("runtest %u cycles, end in %s",
cmd->cmd.runtest->num_cycles,
tap_state_name(cmd->cmd.runtest->end_state));
@@ -115,7 +115,7 @@ static int vsllink_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_PATHMOVE:
- LOG_DEBUG_IO("pathmove: %i states, end in %s",
+ LOG_DEBUG_IO("pathmove: %u states, end in %s",
cmd->cmd.pathmove->num_states,
tap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));
@@ -161,7 +161,7 @@ static int vsllink_execute_queue(struct jtag_command *cmd_queue)
break;
case JTAG_STABLECLOCKS:
- LOG_DEBUG_IO("add %d clocks",
+ LOG_DEBUG_IO("add %u clocks",
cmd->cmd.stableclocks->num_cycles);
switch (tap_get_state()) {
@@ -371,9 +371,9 @@ static void vsllink_state_move(void)
tap_set_state(tap_get_end_state());
}
-static void vsllink_path_move(int num_states, tap_state_t *path)
+static void vsllink_path_move(unsigned int num_states, tap_state_t *path)
{
- for (int i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false))
vsllink_tap_append_step(0, 0);
else if (path[i] == tap_state_transition(tap_get_state(), true))
@@ -397,7 +397,7 @@ static void vsllink_tms(int num_bits, const uint8_t *bits)
vsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);
}
-static void vsllink_stableclocks(int num_cycles, int tms)
+static void vsllink_stableclocks(unsigned int num_cycles, int tms)
{
while (num_cycles > 0) {
vsllink_tap_append_step(tms, 0);
@@ -405,7 +405,7 @@ static void vsllink_stableclocks(int num_cycles, int tms)
}
}
-static void vsllink_runtest(int num_cycles)
+static void vsllink_runtest(unsigned int num_cycles)
{
tap_state_t saved_end_state = tap_get_end_state();
diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c
index 11fbaaa..f252087 100644
--- a/src/jtag/drivers/xds110.c
+++ b/src/jtag/drivers/xds110.c
@@ -1669,7 +1669,6 @@ static void xds110_execute_tlr_reset(struct jtag_command *cmd)
static void xds110_execute_pathmove(struct jtag_command *cmd)
{
- uint32_t i;
uint32_t num_states;
uint8_t *path;
@@ -1685,7 +1684,7 @@ static void xds110_execute_pathmove(struct jtag_command *cmd)
}
/* Convert requested path states into XDS API states */
- for (i = 0; i < num_states; i++)
+ for (unsigned int i = 0; i < num_states; i++)
path[i] = (uint8_t)xds_jtag_state[cmd->cmd.pathmove->path[i]];
if (xds110.firmware >= OCD_FIRMWARE_VERSION) {
@@ -1704,7 +1703,6 @@ static void xds110_execute_pathmove(struct jtag_command *cmd)
static void xds110_queue_scan(struct jtag_command *cmd)
{
- int i;
uint32_t offset;
uint32_t total_fields;
uint32_t total_bits;
@@ -1715,7 +1713,7 @@ static void xds110_queue_scan(struct jtag_command *cmd)
/* Calculate the total number of bits to scan */
total_bits = 0;
total_fields = 0;
- for (i = 0; i < cmd->cmd.scan->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++) {
total_fields++;
total_bits += (uint32_t)cmd->cmd.scan->fields[i].num_bits;
}
@@ -1756,7 +1754,7 @@ static void xds110_queue_scan(struct jtag_command *cmd)
buffer = &xds110.txn_requests[xds110.txn_request_size];
/* Clear data out buffer to default value of all zeros */
memset((void *)buffer, 0x00, total_bytes);
- for (i = 0; i < cmd->cmd.scan->num_fields; i++) {
+ for (unsigned int i = 0; i < cmd->cmd.scan->num_fields; i++) {
if (cmd->cmd.scan->fields[i].out_value) {
/* Copy over data to scan out into request buffer */
bit_copy(buffer, offset, cmd->cmd.scan->fields[i].out_value, 0,
@@ -1775,7 +1773,7 @@ static void xds110_queue_scan(struct jtag_command *cmd)
static void xds110_queue_runtest(struct jtag_command *cmd)
{
- uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;
+ uint32_t clocks = cmd->cmd.stableclocks->num_cycles;
uint8_t end_state = (uint8_t)xds_jtag_state[cmd->cmd.runtest->end_state];
/* Check if new request would be too large to fit */
@@ -1794,7 +1792,7 @@ static void xds110_queue_runtest(struct jtag_command *cmd)
static void xds110_queue_stableclocks(struct jtag_command *cmd)
{
- uint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;
+ uint32_t clocks = cmd->cmd.stableclocks->num_cycles;
/* Check if new request would be too large to fit */
if ((xds110.txn_request_size + 1 + sizeof(clocks) + 1) > MAX_DATA_BLOCK)
diff --git a/src/jtag/drivers/xlnx-pcie-xvc.c b/src/jtag/drivers/xlnx-pcie-xvc.c
index 233ade3..b5c7e2f 100644
--- a/src/jtag/drivers/xlnx-pcie-xvc.c
+++ b/src/jtag/drivers/xlnx-pcie-xvc.c
@@ -128,7 +128,7 @@ static int xlnx_pcie_xvc_execute_stableclocks(struct jtag_command *cmd)
size_t write;
int err;
- LOG_DEBUG("stableclocks %i cycles", cmd->cmd.runtest->num_cycles);
+ LOG_DEBUG("stableclocks %u cycles", cmd->cmd.runtest->num_cycles);
while (left) {
write = MIN(XLNX_XVC_MAX_BITS, left);
@@ -167,7 +167,7 @@ static int xlnx_pcie_xvc_execute_runtest(struct jtag_command *cmd)
{
int err = ERROR_OK;
- LOG_DEBUG("runtest %i cycles, end in %i",
+ LOG_DEBUG("runtest %u cycles, end in %i",
cmd->cmd.runtest->num_cycles,
cmd->cmd.runtest->end_state);
@@ -200,16 +200,15 @@ static int xlnx_pcie_xvc_execute_runtest(struct jtag_command *cmd)
static int xlnx_pcie_xvc_execute_pathmove(struct jtag_command *cmd)
{
- size_t num_states = cmd->cmd.pathmove->num_states;
+ unsigned int num_states = cmd->cmd.pathmove->num_states;
tap_state_t *path = cmd->cmd.pathmove->path;
int err = ERROR_OK;
- size_t i;
- LOG_DEBUG("pathmove: %i states, end in %i",
+ LOG_DEBUG("pathmove: %u states, end in %i",
cmd->cmd.pathmove->num_states,
cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
- for (i = 0; i < num_states; i++) {
+ for (unsigned int i = 0; i < num_states; i++) {
if (path[i] == tap_state_transition(tap_get_state(), false)) {
err = xlnx_pcie_xvc_transact(1, 1, 0, NULL);
} else if (path[i] == tap_state_transition(tap_get_state(), true)) {
diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c
index 6ac6801..c73f6c8 100644
--- a/src/jtag/hla/hla_interface.c
+++ b/src/jtag/hla/hla_interface.c
@@ -319,37 +319,37 @@ COMMAND_HANDLER(interface_handle_hla_command)
return ERROR_OK;
}
-static const struct command_registration hl_interface_command_handlers[] = {
+static const struct command_registration hl_interface_subcommand_handlers[] = {
{
- .name = "hla_device_desc",
+ .name = "device_desc",
.handler = &hl_interface_handle_device_desc_command,
.mode = COMMAND_CONFIG,
.help = "set the device description of the adapter",
.usage = "description_string",
},
{
- .name = "hla_layout",
+ .name = "layout",
.handler = &hl_interface_handle_layout_command,
.mode = COMMAND_CONFIG,
.help = "set the layout of the adapter",
.usage = "layout_name",
},
{
- .name = "hla_vid_pid",
+ .name = "vid_pid",
.handler = &hl_interface_handle_vid_pid_command,
.mode = COMMAND_CONFIG,
.help = "the vendor and product ID of the adapter",
.usage = "(vid pid)*",
},
{
- .name = "hla_stlink_backend",
+ .name = "stlink_backend",
.handler = &hl_interface_handle_stlink_backend_command,
.mode = COMMAND_CONFIG,
.help = "select which ST-Link backend to use",
.usage = "usb | tcp [port]",
},
{
- .name = "hla_command",
+ .name = "command",
.handler = &interface_handle_hla_command,
.mode = COMMAND_EXEC,
.help = "execute a custom adapter-specific command",
@@ -358,6 +358,17 @@ static const struct command_registration hl_interface_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration hl_interface_command_handlers[] = {
+ {
+ .name = "hla",
+ .mode = COMMAND_ANY,
+ .help = "perform hla management",
+ .chain = hl_interface_subcommand_handlers,
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
struct adapter_driver hl_adapter_driver = {
.name = "hla",
.transports = hl_transports,
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 470ae18..b9d37b3 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -86,7 +86,7 @@ extern tap_state_t cmd_queue_cur_state;
*/
struct scan_field {
/** The number of bits this field specifies */
- int num_bits;
+ unsigned int num_bits;
/** A pointer to value to be scanned into the device */
const uint8_t *out_value;
/** A pointer to a 32-bit memory location for data scanned out */
@@ -102,12 +102,12 @@ struct jtag_tap {
char *chip;
char *tapname;
char *dotted_name;
- int abs_chain_position;
+ unsigned int abs_chain_position;
/** Is this TAP disabled after JTAG reset? */
bool disabled_after_reset;
/** Is this TAP currently enabled? */
bool enabled;
- int ir_length; /**< size of instruction register */
+ unsigned int ir_length; /**< size of instruction register */
uint32_t ir_capture_value;
uint8_t *expected; /**< Capture-IR expected value */
uint32_t ir_capture_mask;
@@ -150,10 +150,10 @@ struct jtag_tap *jtag_all_taps(void);
const char *jtag_tap_name(const struct jtag_tap *tap);
struct jtag_tap *jtag_tap_by_string(const char *dotted_name);
struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *obj);
-struct jtag_tap *jtag_tap_by_position(unsigned abs_position);
+struct jtag_tap *jtag_tap_by_position(unsigned int abs_position);
struct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p);
-unsigned jtag_tap_count_enabled(void);
-unsigned jtag_tap_count(void);
+unsigned int jtag_tap_count_enabled(void);
+unsigned int jtag_tap_count(void);
/*
* - TRST_ASSERTED triggers two sets of callbacks, after operations to
@@ -229,17 +229,17 @@ enum reset_types {
enum reset_types jtag_get_reset_config(void);
void jtag_set_reset_config(enum reset_types type);
-void jtag_set_nsrst_delay(unsigned delay);
-unsigned jtag_get_nsrst_delay(void);
+void jtag_set_nsrst_delay(unsigned int delay);
+unsigned int jtag_get_nsrst_delay(void);
-void jtag_set_ntrst_delay(unsigned delay);
-unsigned jtag_get_ntrst_delay(void);
+void jtag_set_ntrst_delay(unsigned int delay);
+unsigned int jtag_get_ntrst_delay(void);
-void jtag_set_nsrst_assert_width(unsigned delay);
-unsigned jtag_get_nsrst_assert_width(void);
+void jtag_set_nsrst_assert_width(unsigned int delay);
+unsigned int jtag_get_nsrst_assert_width(void);
-void jtag_set_ntrst_assert_width(unsigned delay);
-unsigned jtag_get_ntrst_assert_width(void);
+void jtag_set_ntrst_assert_width(unsigned int delay);
+unsigned int jtag_get_ntrst_assert_width(void);
/** @returns The current state of TRST. */
int jtag_get_trst(void);
@@ -436,7 +436,7 @@ void jtag_add_tlr(void);
* - ERROR_JTAG_TRANSITION_INVALID -- The path includes invalid
* state transitions.
*/
-void jtag_add_pathmove(int num_states, const tap_state_t *path);
+void jtag_add_pathmove(unsigned int num_states, const tap_state_t *path);
/**
* jtag_add_statemove() moves from the current state to @a goal_state.
@@ -459,7 +459,7 @@ int jtag_add_statemove(tap_state_t goal_state);
* via TAP_IDLE.
* @param endstate The final state.
*/
-void jtag_add_runtest(int num_cycles, tap_state_t endstate);
+void jtag_add_runtest(unsigned int num_cycles, tap_state_t endstate);
/**
* A reset of the TAP state machine can be requested.
@@ -488,14 +488,14 @@ void jtag_add_reset(int req_tlr_or_trst, int srst);
void jtag_add_sleep(uint32_t us);
-int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state t);
+int jtag_add_tms_seq(unsigned int nbits, const uint8_t *seq, enum tap_state t);
/**
* Function jtag_add_clocks
* first checks that the state in which the clocks are to be issued is
* stable, then queues up num_cycles clocks for transmission.
*/
-void jtag_add_clocks(int num_cycles);
+void jtag_add_clocks(unsigned int num_cycles);
/**
* For software FIFO implementations, the queued commands can be executed
@@ -523,7 +523,7 @@ int jtag_execute_queue(void);
void jtag_execute_queue_noclear(void);
/** @returns the number of times the scan queue has been flushed */
-int jtag_get_flush_queue_count(void);
+unsigned int jtag_get_flush_queue_count(void);
/** Report Tcl event to all TAPs */
void jtag_notify_event(enum jtag_event);
diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h
index a40cffa..45b0bf6 100644
--- a/src/jtag/minidriver.h
+++ b/src/jtag/minidriver.h
@@ -51,8 +51,8 @@ int interface_jtag_add_plain_dr_scan(
tap_state_t endstate);
int interface_jtag_add_tlr(void);
-int interface_jtag_add_pathmove(int num_states, const tap_state_t *path);
-int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate);
+int interface_jtag_add_pathmove(unsigned int num_states, const tap_state_t *path);
+int interface_jtag_add_runtest(unsigned int num_cycles, tap_state_t endstate);
int interface_add_tms_seq(unsigned num_bits,
const uint8_t *bits, enum tap_state state);
@@ -67,7 +67,7 @@ int interface_add_tms_seq(unsigned num_bits,
*/
int interface_jtag_add_reset(int trst, int srst);
int interface_jtag_add_sleep(uint32_t us);
-int interface_jtag_add_clocks(int num_cycles);
+int interface_jtag_add_clocks(unsigned int num_cycles);
int interface_jtag_execute_queue(void);
/**
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index 41db38e..2d8ebf0 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -1126,6 +1126,36 @@ proc "cmsis_dap_usb" {args} {
eval cmsis-dap usb $args
}
+lappend _telnet_autocomplete_skip "hla_layout"
+proc "hla_layout" {layout} {
+ echo "DEPRECATED! use 'hla layout', not 'hla_layout'"
+ eval hla layout $layout
+}
+
+lappend _telnet_autocomplete_skip "hla_device_desc"
+proc "hla_device_desc" {desc} {
+ echo "DEPRECATED! use 'hla device_desc', not 'hla_device_desc'"
+ eval hla device_desc $desc
+}
+
+lappend _telnet_autocomplete_skip "hla_vid_pid"
+proc "hla_vid_pid" {args} {
+ echo "DEPRECATED! use 'hla vid_pid', not 'hla_vid_pid'"
+ eval hla vid_pid $args
+}
+
+lappend _telnet_autocomplete_skip "hla_command"
+proc "hla_command" {command} {
+ echo "DEPRECATED! use 'hla command', not 'hla_command'"
+ eval hla command $command
+}
+
+lappend _telnet_autocomplete_skip "hla_stlink_backend"
+proc "hla_stlink_backend" {args} {
+ echo "DEPRECATED! use 'hla stlink_backend', not 'hla_stlink_backend'"
+ eval hla stlink_backend $args
+}
+
lappend _telnet_autocomplete_skip "kitprog_init_acquire_psoc"
proc "kitprog_init_acquire_psoc" {} {
echo "DEPRECATED! use 'kitprog init_acquire_psoc', not 'kitprog_init_acquire_psoc'"
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 1a4c4b7..10a7dd3 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -87,8 +87,11 @@ static COMMAND_HELPER(handle_jtag_command_drscan_fields, struct scan_field *fiel
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
+
fields[field_count].out_value = t;
- str_to_buf(CMD_ARGV[i + 1], strlen(CMD_ARGV[i + 1]), t, bits, 0);
+ int ret = CALL_COMMAND_HANDLER(command_parse_str_to_buf, CMD_ARGV[i + 1], t, bits, 0);
+ if (ret != ERROR_OK)
+ return ret;
fields[field_count].in_value = t;
field_count++;
}
@@ -209,8 +212,8 @@ COMMAND_HANDLER(handle_jtag_flush_count)
if (CMD_ARGC != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
- int count = jtag_get_flush_queue_count();
- command_print_sameline(CMD, "%d", count);
+ const unsigned int count = jtag_get_flush_queue_count();
+ command_print_sameline(CMD, "%u", count);
return ERROR_OK;
}
@@ -445,11 +448,11 @@ static COMMAND_HELPER(handle_jtag_newtap_args, struct jtag_tap *tap)
if (!CMD_ARGC)
return ERROR_COMMAND_ARGUMENT_INVALID;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tap->ir_length);
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], tap->ir_length);
CMD_ARGC--;
CMD_ARGV++;
- if (tap->ir_length > (int)(8 * sizeof(tap->ir_capture_value)))
- LOG_WARNING("%s: huge IR length %d", tap->dotted_name, tap->ir_length);
+ if (tap->ir_length > (8 * sizeof(tap->ir_capture_value)))
+ LOG_WARNING("%s: huge IR length %u", tap->dotted_name, tap->ir_length);
break;
case NTAP_OPT_IRMASK:
@@ -811,13 +814,13 @@ COMMAND_HANDLER(handle_scan_chain_command)
expected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);
command_print(CMD,
- "%2d %-18s %c 0x%08x %s %5d 0x%02x 0x%02x",
+ "%2u %-18s %c 0x%08x %s %5u 0x%02x 0x%02x",
tap->abs_chain_position,
tap->dotted_name,
tap->enabled ? 'Y' : 'n',
(unsigned int)(tap->idcode),
expected_id,
- (unsigned int)(tap->ir_length),
+ tap->ir_length,
(unsigned int)(expected),
(unsigned int)(expected_mask));
@@ -969,7 +972,7 @@ COMMAND_HANDLER(handle_irscan_command)
if (retval != ERROR_OK)
goto error_return;
- int field_size = tap->ir_length;
+ unsigned int field_size = tap->ir_length;
fields[i].num_bits = field_size;
uint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8));
if (!v) {
diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index f256bc2..b2339bb 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -36,7 +36,18 @@ struct target *hwthread_swbp_target(struct rtos *rtos, target_addr_t address,
static inline threadid_t threadid_from_target(const struct target *target)
{
- return target->coreid + 1;
+ if (!target->smp)
+ return 1;
+
+ threadid_t threadid = 1;
+ struct target_list *head;
+ foreach_smp_target(head, target->smp_targets) {
+ if (target == head->target)
+ return threadid;
+ ++threadid;
+ }
+ assert(0 && "Target is not found in it's own SMP group!");
+ return -1;
}
const struct rtos_type hwthread_rtos = {
@@ -59,14 +70,13 @@ struct hwthread_params {
int dummy_param;
};
-static int hwthread_fill_thread(struct rtos *rtos, struct target *curr, int thread_num)
+static int hwthread_fill_thread(struct rtos *rtos, struct target *curr, int thread_num, threadid_t tid)
{
char tmp_str[HW_THREAD_NAME_STR_SIZE];
- threadid_t tid = threadid_from_target(curr);
memset(tmp_str, 0, HW_THREAD_NAME_STR_SIZE);
- /* thread-id is the core-id of this core inside the SMP group plus 1 */
+ /* thread-id is the index of this core inside the SMP group plus 1 */
rtos->thread_details[thread_num].threadid = tid;
/* create the thread name */
rtos->thread_details[thread_num].exists = true;
@@ -130,9 +140,8 @@ static int hwthread_update_threads(struct rtos *rtos)
curr->state == TARGET_UNAVAILABLE)
continue;
- threadid_t tid = threadid_from_target(curr);
-
- hwthread_fill_thread(rtos, curr, threads_found);
+ threadid_t tid = threads_found + 1;
+ hwthread_fill_thread(rtos, curr, threads_found, tid);
/* find an interesting thread to set as current */
switch (current_reason) {
@@ -189,8 +198,8 @@ static int hwthread_update_threads(struct rtos *rtos)
threads_found++;
}
} else {
- hwthread_fill_thread(rtos, target, threads_found);
- current_thread = threadid_from_target(target);
+ current_thread = 1;
+ hwthread_fill_thread(rtos, target, threads_found, current_thread);
threads_found++;
}
@@ -213,19 +222,17 @@ static int hwthread_smp_init(struct target *target)
return hwthread_update_threads(target->rtos);
}
-static struct target *hwthread_find_thread(struct target *target, int64_t thread_id)
+static struct target *hwthread_find_thread(struct target *target, threadid_t thread_id)
{
- /* Find the thread with that thread_id */
- if (!target)
- return NULL;
- if (target->smp) {
- struct target_list *head;
- foreach_smp_target(head, target->smp_targets) {
- if (thread_id == threadid_from_target(head->target))
- return head->target;
- }
- } else if (thread_id == threadid_from_target(target)) {
+ /* Find the thread with that thread_id (index in SMP group plus 1)*/
+ if (!(target && target->smp))
return target;
+ struct target_list *head;
+ threadid_t tid = 1;
+ foreach_smp_target(head, target->smp_targets) {
+ if (thread_id == tid)
+ return head->target;
+ ++tid;
}
return NULL;
}
@@ -304,7 +311,7 @@ static int hwthread_get_thread_reg_value(struct rtos *rtos, int64_t thread_id,
}
if (!target_was_examined(curr)) {
- LOG_ERROR("Target %d hasn't been examined yet.", curr->coreid);
+ LOG_TARGET_ERROR(curr, "Target hasn't been examined yet.");
return ERROR_FAIL;
}
@@ -392,9 +399,9 @@ static int hwthread_thread_packet(struct connection *connection, const char *pac
return ERROR_FAIL;
}
target->rtos->current_thread = current_threadid;
- } else
- if (current_threadid == 0 || current_threadid == -1)
+ } else if (current_threadid == 0 || current_threadid == -1) {
target->rtos->current_thread = threadid_from_target(target);
+ }
target->rtos->current_threadid = current_threadid;
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index f4ce5df..6c4931b 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1599,7 +1599,7 @@ static int gdb_read_memory_packet(struct connection *connection,
* cmd = view%20audit-trail&database = gdb&pr = 2395
*
* For now, the default is to fix up things to make current GDB versions work.
- * This can be overwritten using the gdb_report_data_abort <'enable'|'disable'> command.
+ * This can be overwritten using the "gdb report_data_abort <'enable'|'disable'>" command.
*/
memset(buffer, 0, len);
retval = ERROR_OK;
@@ -4034,7 +4034,7 @@ COMMAND_HANDLER(handle_gdb_sync_command)
if (!current_gdb_connection) {
command_print(CMD,
- "gdb_sync command can only be run from within gdb using \"monitor gdb_sync\"");
+ "gdb sync command can only be run from within gdb using \"monitor gdb sync\"");
return ERROR_FAIL;
}
@@ -4043,7 +4043,6 @@ COMMAND_HANDLER(handle_gdb_sync_command)
return ERROR_OK;
}
-/* daemon configuration command gdb_port */
COMMAND_HANDLER(handle_gdb_port_command)
{
int retval = CALL_COMMAND_HANDLER(server_pipe_command, &gdb_port);
@@ -4090,7 +4089,6 @@ COMMAND_HANDLER(handle_gdb_report_register_access_error)
return ERROR_OK;
}
-/* gdb_breakpoint_override */
COMMAND_HANDLER(handle_gdb_breakpoint_override_command)
{
if (CMD_ARGC == 0) {
@@ -4167,9 +4165,9 @@ out:
return retval;
}
-static const struct command_registration gdb_command_handlers[] = {
+static const struct command_registration gdb_subcommand_handlers[] = {
{
- .name = "gdb_sync",
+ .name = "sync",
.handler = handle_gdb_sync_command,
.mode = COMMAND_ANY,
.help = "next stepi will return immediately allowing "
@@ -4178,7 +4176,7 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = ""
},
{
- .name = "gdb_port",
+ .name = "port",
.handler = handle_gdb_port_command,
.mode = COMMAND_CONFIG,
.help = "Normally gdb listens to a TCP/IP port. Each subsequent GDB "
@@ -4191,35 +4189,35 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = "[port_num]",
},
{
- .name = "gdb_memory_map",
+ .name = "memory_map",
.handler = handle_gdb_memory_map_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable memory map",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_flash_program",
+ .name = "flash_program",
.handler = handle_gdb_flash_program_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable flash program",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_report_data_abort",
+ .name = "report_data_abort",
.handler = handle_gdb_report_data_abort_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable reporting data aborts",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_report_register_access_error",
+ .name = "report_register_access_error",
.handler = handle_gdb_report_register_access_error,
.mode = COMMAND_CONFIG,
.help = "enable or disable reporting register access errors",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_breakpoint_override",
+ .name = "breakpoint_override",
.handler = handle_gdb_breakpoint_override_command,
.mode = COMMAND_ANY,
.help = "Display or specify type of breakpoint "
@@ -4227,14 +4225,14 @@ static const struct command_registration gdb_command_handlers[] = {
.usage = "('hard'|'soft'|'disable')"
},
{
- .name = "gdb_target_description",
+ .name = "target_description",
.handler = handle_gdb_target_description_command,
.mode = COMMAND_CONFIG,
.help = "enable or disable target description",
.usage = "('enable'|'disable')"
},
{
- .name = "gdb_save_tdesc",
+ .name = "save_tdesc",
.handler = handle_gdb_save_tdesc_command,
.mode = COMMAND_EXEC,
.help = "Save the target description file",
@@ -4243,6 +4241,17 @@ static const struct command_registration gdb_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration gdb_command_handlers[] = {
+ {
+ .name = "gdb",
+ .mode = COMMAND_ANY,
+ .help = "GDB commands",
+ .chain = gdb_subcommand_handlers,
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
int gdb_register_commands(struct command_context *cmd_ctx)
{
gdb_port = strdup("3333");
diff --git a/src/server/startup.tcl b/src/server/startup.tcl
index 1d30b1d..ebfb056 100644
--- a/src/server/startup.tcl
+++ b/src/server/startup.tcl
@@ -41,3 +41,75 @@ proc _telnet_autocomplete_helper pattern {
return [lsort $cmds]
}
+
+lappend _telnet_autocomplete_skip "gdb_sync"
+proc "gdb_sync" {} {
+ echo "DEPRECATED! use 'gdb sync', not 'gdb_sync'"
+ eval gdb sync
+}
+
+lappend _telnet_autocomplete_skip "gdb_port"
+proc "gdb_port" {args} {
+ echo "DEPRECATED! use 'gdb port', not 'gdb_port'"
+ eval gdb port $args
+}
+
+lappend _telnet_autocomplete_skip "gdb_memory_map"
+proc "gdb_memory_map" {state} {
+ echo "DEPRECATED! use 'gdb memory_map', not 'gdb_memory_map'"
+ eval gdb memory_map $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_flash_program"
+proc "gdb_flash_program" {state} {
+ echo "DEPRECATED! use 'gdb flash_program', not 'gdb_flash_program'"
+ eval gdb flash_program $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_report_data_abort"
+proc "gdb_report_data_abort" {state} {
+ echo "DEPRECATED! use 'gdb report_data_abort', not 'gdb_report_data_abort'"
+ eval gdb report_data_abort $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_report_register_access_error"
+proc "gdb_report_register_access_error" {state} {
+ echo "DEPRECATED! use 'gdb report_register_access_error', not 'gdb_report_register_access_error'"
+ eval gdb report_register_access_error $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_breakpoint_override"
+proc "gdb_breakpoint_override" {override} {
+ echo "DEPRECATED! use 'gdb breakpoint_override', not 'gdb_breakpoint_override'"
+ eval gdb breakpoint_override $override
+}
+
+lappend _telnet_autocomplete_skip "gdb_target_description"
+proc "gdb_target_description" {state} {
+ echo "DEPRECATED! use 'gdb target_description', not 'gdb_target_description'"
+ eval gdb target_description $state
+}
+
+lappend _telnet_autocomplete_skip "gdb_save_tdesc"
+proc "gdb_save_tdesc" {} {
+ echo "DEPRECATED! use 'gdb save_tdesc', not 'gdb_save_tdesc'"
+ eval gdb save_tdesc
+}
+
+lappend _telnet_autocomplete_skip "tcl_port"
+proc "tcl_port" {args} {
+ echo "DEPRECATED! use 'tcl port' not 'tcl_port'"
+ eval tcl port $args
+}
+
+lappend _telnet_autocomplete_skip "tcl_notifications"
+proc "tcl_notifications" {state} {
+ echo "DEPRECATED! use 'tcl notifications' not 'tcl_notifications'"
+ eval tcl notifications $state
+}
+
+lappend _telnet_autocomplete_skip "tcl_trace"
+proc "tcl_trace" {state} {
+ echo "DEPRECATED! use 'tcl trace' not 'tcl_trace'"
+ eval tcl trace $state
+}
diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c
index 16cbedc..16cc55e 100644
--- a/src/server/tcl_server.c
+++ b/src/server/tcl_server.c
@@ -323,25 +323,25 @@ COMMAND_HANDLER(handle_tcl_trace_command)
}
}
-static const struct command_registration tcl_command_handlers[] = {
+static const struct command_registration tcl_subcommand_handlers[] = {
{
- .name = "tcl_port",
+ .name = "port",
.handler = handle_tcl_port_command,
.mode = COMMAND_CONFIG,
.help = "Specify port on which to listen "
"for incoming Tcl syntax. "
- "Read help on 'gdb_port'.",
+ "Read help on 'gdb port'.",
.usage = "[port_num]",
},
{
- .name = "tcl_notifications",
+ .name = "notifications",
.handler = handle_tcl_notifications_command,
.mode = COMMAND_EXEC,
.help = "Target Notification output",
.usage = "[on|off]",
},
{
- .name = "tcl_trace",
+ .name = "trace",
.handler = handle_tcl_trace_command,
.mode = COMMAND_EXEC,
.help = "Target trace output",
@@ -350,6 +350,17 @@ static const struct command_registration tcl_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
+static const struct command_registration tcl_command_handlers[] = {
+ {
+ .name = "tcl",
+ .mode = COMMAND_ANY,
+ .help = "tcl command group",
+ .usage = "",
+ .chain = tcl_subcommand_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
int tcl_register_commands(struct command_context *cmd_ctx)
{
tcl_port = strdup("6666");
diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c
index 938bc5b..02d450f 100644
--- a/src/server/telnet_server.c
+++ b/src/server/telnet_server.c
@@ -982,7 +982,7 @@ static const struct command_registration telnet_command_handlers[] = {
{
.name = "exit",
.handler = handle_exit_command,
- .mode = COMMAND_EXEC,
+ .mode = COMMAND_ANY,
.usage = "",
.help = "exit telnet session",
},
@@ -992,7 +992,7 @@ static const struct command_registration telnet_command_handlers[] = {
.mode = COMMAND_CONFIG,
.help = "Specify port on which to listen "
"for incoming telnet connections. "
- "Read help on 'gdb_port'.",
+ "Read help on 'gdb port'.",
.usage = "[port_num]",
},
COMMAND_REGISTRATION_DONE
diff --git a/src/target/arm.h b/src/target/arm.h
index 486666b..0de322a 100644
--- a/src/target/arm.h
+++ b/src/target/arm.h
@@ -58,11 +58,12 @@ enum arm_arch {
ARM_ARCH_V8M,
};
-/** Known ARM implementor IDs */
-enum arm_implementor {
- ARM_IMPLEMENTOR_ARM = 0x41,
- ARM_IMPLEMENTOR_INFINEON = 0x49,
- ARM_IMPLEMENTOR_REALTEK = 0x72,
+/** Known ARM implementer IDs */
+enum arm_implementer {
+ ARM_IMPLEMENTER_ARM = 0x41,
+ ARM_IMPLEMENTER_INFINEON = 0x49,
+ ARM_IMPLEMENTER_ARM_CHINA = 0x63,
+ ARM_IMPLEMENTER_REALTEK = 0x72,
};
/**
diff --git a/src/target/avrt.c b/src/target/avrt.c
index 61bef32..8886a46 100644
--- a/src/target/avrt.c
+++ b/src/target/avrt.c
@@ -31,10 +31,10 @@ static int avr_assert_reset(struct target *target);
static int avr_deassert_reset(struct target *target);
/* IR and DR functions */
-static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len, int rti);
-static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_len, int rti);
-static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti);
-static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len, int rti);
+static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len);
+static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_len);
+static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len);
+static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len);
struct target_type avr_target = {
.name = "avr",
@@ -137,23 +137,23 @@ static int avr_deassert_reset(struct target *target)
int avr_jtag_senddat(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out,
int len)
{
- return mcu_write_dr_u32(tap, dr_in, dr_out, len, 1);
+ return mcu_write_dr_u32(tap, dr_in, dr_out, len);
}
int avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out)
{
- return mcu_write_ir_u8(tap, ir_in, ir_out, AVR_JTAG_INS_LEN, 1);
+ return mcu_write_ir_u8(tap, ir_in, ir_out, AVR_JTAG_INS_LEN);
}
/* IR and DR functions */
static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out,
- int ir_len, int rti)
+ int ir_len)
{
if (!tap) {
LOG_ERROR("invalid tap");
return ERROR_FAIL;
}
- if (ir_len != tap->ir_length) {
+ if ((unsigned int)ir_len != tap->ir_length) {
LOG_ERROR("invalid ir_len");
return ERROR_FAIL;
}
@@ -166,7 +166,7 @@ static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out,
}
static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out,
- int dr_len, int rti)
+ int dr_len)
{
if (!tap) {
LOG_ERROR("invalid tap");
@@ -181,27 +181,27 @@ static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out,
}
static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in,
- uint8_t ir_out, int ir_len, int rti)
+ uint8_t ir_out, int ir_len)
{
if (ir_len > 8) {
LOG_ERROR("ir_len overflow, maximum is 8");
return ERROR_FAIL;
}
- mcu_write_ir(tap, ir_in, &ir_out, ir_len, rti);
+ mcu_write_ir(tap, ir_in, &ir_out, ir_len);
return ERROR_OK;
}
static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in,
- uint32_t dr_out, int dr_len, int rti)
+ uint32_t dr_out, int dr_len)
{
if (dr_len > 32) {
LOG_ERROR("dr_len overflow, maximum is 32");
return ERROR_FAIL;
}
- mcu_write_dr(tap, (uint8_t *)dr_in, (uint8_t *)&dr_out, dr_len, rti);
+ mcu_write_dr(tap, (uint8_t *)dr_in, (uint8_t *)&dr_out, dr_len);
return ERROR_OK;
}
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 34c7cd4..3b95b64 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -100,6 +100,12 @@ static const struct cortex_m_part_info cortex_m_parts[] = {
.flags = CORTEX_M_F_HAS_FPV5,
},
{
+ .impl_part = CORTEX_M52_PARTNO,
+ .name = "Cortex-M52",
+ .arch = ARM_ARCH_V8M,
+ .flags = CORTEX_M_F_HAS_FPV5,
+ },
+ {
.impl_part = CORTEX_M55_PARTNO,
.name = "Cortex-M55",
.arch = ARM_ARCH_V8M,
@@ -273,7 +279,8 @@ static int cortex_m_fast_read_all_regs(struct target *target)
/* because the DCB_DCRDR is used for the emulated dcc channel
* we have to save/restore the DCB_DCRDR when used */
- if (target->dbg_msg_enabled) {
+ bool dbg_msg_enabled = target->dbg_msg_enabled;
+ if (dbg_msg_enabled) {
retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);
if (retval != ERROR_OK)
return retval;
@@ -326,7 +333,7 @@ static int cortex_m_fast_read_all_regs(struct target *target)
if (retval != ERROR_OK)
return retval;
- if (target->dbg_msg_enabled) {
+ if (dbg_msg_enabled) {
/* restore DCB_DCRDR - this needs to be in a separate
* transaction otherwise the emulated DCC channel breaks */
retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);
@@ -797,6 +804,42 @@ static int cortex_m_examine_exception_reason(struct target *target)
return retval;
}
+/* Errata 3092511 workaround
+ * Cortex-M7 can halt in an incorrect address when breakpoint
+ * and exception occurs simultaneously */
+static int cortex_m_erratum_check_breakpoint(struct target *target)
+{
+ struct cortex_m_common *cortex_m = target_to_cm(target);
+ struct armv7m_common *armv7m = &cortex_m->armv7m;
+ struct arm *arm = &armv7m->arm;
+
+ uint32_t pc = buf_get_u32(arm->pc->value, 0, 32);
+
+ /* To reduce the workaround processing cost we assume FPB is in sync
+ * with OpenOCD breakpoints. If the target app writes to FPB
+ * OpenOCD will resume after the break set by app */
+ struct breakpoint *bkpt = breakpoint_find(target, pc);
+ if (bkpt) {
+ LOG_TARGET_DEBUG(target, "Erratum 3092511: breakpoint confirmed");
+ return ERROR_OK;
+ }
+ if (pc >= 0xe0000000u)
+ /* not executable area, do not read instruction @ pc */
+ return ERROR_OK;
+
+ uint16_t insn;
+ int retval = target_read_u16(target, pc, &insn);
+ if (retval != ERROR_OK)
+ return ERROR_OK; /* do not propagate the error, just avoid workaround */
+
+ if ((insn & 0xff00) == (ARMV5_T_BKPT(0) & 0xff00)) {
+ LOG_TARGET_DEBUG(target, "Erratum 3092511: breakpoint embedded in code confirmed");
+ return ERROR_OK;
+ }
+ LOG_TARGET_DEBUG(target, "Erratum 3092511: breakpoint not found, proceed with resume");
+ return ERROR_TARGET_HALTED_DO_RESUME;
+}
+
static int cortex_m_debug_entry(struct target *target)
{
uint32_t xpsr;
@@ -883,6 +926,17 @@ static int cortex_m_debug_entry(struct target *target)
secure_state ? "Secure" : "Non-Secure",
target_state_name(target));
+ /* Errata 3092511 workaround
+ * Cortex-M7 can halt in an incorrect address when breakpoint
+ * and exception occurs simultaneously */
+ if (cortex_m->incorrect_halt_erratum
+ && armv7m->exception_number
+ && cortex_m->nvic_dfsr == (DFSR_BKPT | DFSR_HALTED)) {
+ retval = cortex_m_erratum_check_breakpoint(target);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
if (armv7m->post_debug_entry) {
retval = armv7m->post_debug_entry(target);
if (retval != ERROR_OK)
@@ -960,6 +1014,28 @@ static int cortex_m_poll_one(struct target *target)
if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) {
retval = cortex_m_debug_entry(target);
+ /* Errata 3092511 workaround
+ * Cortex-M7 can halt in an incorrect address when breakpoint
+ * and exception occurs simultaneously */
+ if (retval == ERROR_TARGET_HALTED_DO_RESUME) {
+ struct arm *arm = &armv7m->arm;
+ LOG_TARGET_INFO(target, "Resuming after incorrect halt @ PC 0x%08" PRIx32
+ ", ARM Cortex-M7 erratum 3092511",
+ buf_get_u32(arm->pc->value, 0, 32));
+ /* We don't need to restore registers, just restart the core */
+ cortex_m_set_maskints_for_run(target);
+ retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT);
+ if (retval != ERROR_OK)
+ return retval;
+
+ target->debug_reason = DBG_REASON_NOTHALTED;
+ /* registers are now invalid */
+ register_cache_invalidate(armv7m->arm.core_cache);
+
+ target->state = TARGET_RUNNING;
+ return ERROR_OK;
+ }
+
/* arm_semihosting needs to know registers, don't run if debug entry returned error */
if (retval == ERROR_OK && arm_semihosting(target, &retval) != 0)
return retval;
@@ -1582,7 +1658,7 @@ static int cortex_m_step(struct target *target, int current,
cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
retval = cortex_m_debug_entry(target);
- if (retval != ERROR_OK)
+ if (retval != ERROR_OK && retval != ERROR_TARGET_HALTED_DO_RESUME)
return retval;
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
@@ -2537,8 +2613,8 @@ int cortex_m_examine(struct target *target)
if (retval != ERROR_OK)
return retval;
- /* Inspect implementor/part to look for recognized cores */
- unsigned int impl_part = cpuid & (ARM_CPUID_IMPLEMENTOR_MASK | ARM_CPUID_PARTNO_MASK);
+ /* Inspect implementer/part to look for recognized cores */
+ unsigned int impl_part = cpuid & (ARM_CPUID_IMPLEMENTER_MASK | ARM_CPUID_PARTNO_MASK);
for (unsigned int n = 0; n < ARRAY_SIZE(cortex_m_parts); n++) {
if (impl_part == cortex_m_parts[n].impl_part) {
@@ -2560,14 +2636,22 @@ int cortex_m_examine(struct target *target)
(uint8_t)((cpuid >> 0) & 0xf));
cortex_m->maskints_erratum = false;
+ cortex_m->incorrect_halt_erratum = false;
if (impl_part == CORTEX_M7_PARTNO) {
uint8_t rev, patch;
rev = (cpuid >> 20) & 0xf;
patch = (cpuid >> 0) & 0xf;
if ((rev == 0) && (patch < 2)) {
- LOG_TARGET_WARNING(target, "Silicon bug: single stepping may enter pending exception handler!");
+ LOG_TARGET_WARNING(target, "Erratum 702596: single stepping may enter pending exception handler!");
cortex_m->maskints_erratum = true;
}
+ /* TODO: add revision check when a Cortex-M7 revision with fixed 3092511 is out */
+ LOG_TARGET_WARNING(target, "Erratum 3092511: Cortex-M7 can halt in an incorrect address when breakpoint and exception occurs simultaneously");
+ cortex_m->incorrect_halt_erratum = true;
+ if (armv7m->is_hla_target)
+ LOG_WARNING("No erratum 3092511 workaround on hla adapter");
+ else
+ LOG_INFO("The erratum 3092511 workaround will resume after an incorrect halt");
}
LOG_TARGET_DEBUG(target, "cpuid: 0x%8.8" PRIx32 "", cpuid);
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index a585b78..726fca2 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -31,35 +31,36 @@
#define CPUID 0xE000ED00
-#define ARM_CPUID_IMPLEMENTOR_POS 24
-#define ARM_CPUID_IMPLEMENTOR_MASK (0xFF << ARM_CPUID_IMPLEMENTOR_POS)
+#define ARM_CPUID_IMPLEMENTER_POS 24
+#define ARM_CPUID_IMPLEMENTER_MASK (0xFF << ARM_CPUID_IMPLEMENTER_POS)
#define ARM_CPUID_PARTNO_POS 4
#define ARM_CPUID_PARTNO_MASK (0xFFF << ARM_CPUID_PARTNO_POS)
-#define ARM_MAKE_CPUID(impl, partno) ((((impl) << ARM_CPUID_IMPLEMENTOR_POS) & ARM_CPUID_IMPLEMENTOR_MASK) | \
+#define ARM_MAKE_CPUID(impl, partno) ((((impl) << ARM_CPUID_IMPLEMENTER_POS) & ARM_CPUID_IMPLEMENTER_MASK) | \
(((partno) << ARM_CPUID_PARTNO_POS) & ARM_CPUID_PARTNO_MASK))
/** Known Arm Cortex masked CPU Ids
- * This includes the implementor and part number, but _not_ the revision or
+ * This includes the implementer and part number, but _not_ the revision or
* patch fields.
*/
enum cortex_m_impl_part {
CORTEX_M_PARTNO_INVALID,
- STAR_MC1_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0x132), /* FIXME - confirm implementor! */
- CORTEX_M0_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC20),
- CORTEX_M1_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC21),
- CORTEX_M3_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC23),
- CORTEX_M4_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC24),
- CORTEX_M7_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC27),
- CORTEX_M0P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xC60),
- CORTEX_M23_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD20),
- CORTEX_M33_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD21),
- CORTEX_M35P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD31),
- CORTEX_M55_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD22),
- CORTEX_M85_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_ARM, 0xD23),
- INFINEON_SLX2_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_INFINEON, 0xDB0),
- REALTEK_M200_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_REALTEK, 0xd20),
- REALTEK_M300_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTOR_REALTEK, 0xd22),
+ STAR_MC1_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM_CHINA, 0x132),
+ CORTEX_M0_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC20),
+ CORTEX_M1_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC21),
+ CORTEX_M3_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC23),
+ CORTEX_M4_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC24),
+ CORTEX_M7_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC27),
+ CORTEX_M0P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xC60),
+ CORTEX_M23_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD20),
+ CORTEX_M33_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD21),
+ CORTEX_M35P_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD31),
+ CORTEX_M52_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM_CHINA, 0xD24),
+ CORTEX_M55_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD22),
+ CORTEX_M85_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_ARM, 0xD23),
+ INFINEON_SLX2_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_INFINEON, 0xDB0),
+ REALTEK_M200_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_REALTEK, 0xd20),
+ REALTEK_M300_PARTNO = ARM_MAKE_CPUID(ARM_IMPLEMENTER_REALTEK, 0xd22),
};
/* Relevant Cortex-M flags, used in struct cortex_m_part_info.flags */
@@ -256,6 +257,10 @@ struct cortex_m_common {
/* Whether this target has the erratum that makes C_MASKINTS not apply to
* already pending interrupts */
bool maskints_erratum;
+
+ /* Errata 3092511 Cortex-M7 can halt in an incorrect address when breakpoint
+ * and exception occurs simultaneously */
+ bool incorrect_halt_erratum;
};
static inline bool is_cortex_m_or_hla(const struct cortex_m_common *cortex_m)
diff --git a/src/target/esirisc.c b/src/target/esirisc.c
index 0f76b59..14d34ff 100644
--- a/src/target/esirisc.c
+++ b/src/target/esirisc.c
@@ -483,7 +483,7 @@ static int esirisc_add_breakpoint(struct target *target, struct breakpoint *brea
* The default linker scripts provided by the eSi-RISC toolchain do
* not specify attributes on memory regions, which results in
* incorrect application of software breakpoints by GDB. Targets
- * must be configured with `gdb_breakpoint_override hard` as
+ * must be configured with `gdb breakpoint_override hard` as
* software breakpoints are not supported.
*/
if (breakpoint->type != BKPT_HARD)
diff --git a/src/target/esirisc_jtag.c b/src/target/esirisc_jtag.c
index 1ec1726..5960e26 100644
--- a/src/target/esirisc_jtag.c
+++ b/src/target/esirisc_jtag.c
@@ -58,11 +58,12 @@ static int esirisc_jtag_get_padding(void)
return padding;
}
-static int esirisc_jtag_count_bits(int num_fields, struct scan_field *fields)
+static int esirisc_jtag_count_bits(unsigned int num_fields,
+ struct scan_field *fields)
{
int bit_count = 0;
- for (int i = 0; i < num_fields; ++i)
+ for (unsigned int i = 0; i < num_fields; ++i)
bit_count += fields[i].num_bits;
return bit_count;
diff --git a/src/target/lakemont.c b/src/target/lakemont.c
index 6c0964b..1fcd642 100644
--- a/src/target/lakemont.c
+++ b/src/target/lakemont.c
@@ -224,10 +224,10 @@ static int irscan(struct target *t, uint8_t *out,
if (ir_len != t->tap->ir_length) {
retval = ERROR_FAIL;
if (t->tap->enabled)
- LOG_ERROR("%s tap enabled but tap irlen=%d",
+ LOG_ERROR("%s tap enabled but tap irlen=%u",
__func__, t->tap->ir_length);
else
- LOG_ERROR("%s tap not enabled and irlen=%d",
+ LOG_ERROR("%s tap not enabled and irlen=%u",
__func__, t->tap->ir_length);
return retval;
}
diff --git a/src/target/riscv/asm.h b/src/target/riscv/asm.h
index 6ceb8c9..828cd86 100644
--- a/src/target/riscv/asm.h
+++ b/src/target/riscv/asm.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__ASM_H
-#define TARGET__RISCV__ASM_H
+#ifndef OPENOCD_TARGET_RISCV_ASM_H
+#define OPENOCD_TARGET_RISCV_ASM_H
#include "riscv.h"
@@ -37,4 +37,4 @@ static uint32_t store(const struct target *target, unsigned int src,
return 0; /* Silence -Werror=return-type */
}
-#endif
+#endif /* OPENOCD_TARGET_RISCV_ASM_H */
diff --git a/src/target/riscv/batch.c b/src/target/riscv/batch.c
index bb1070a..afea316 100644
--- a/src/target/riscv/batch.c
+++ b/src/target/riscv/batch.c
@@ -190,8 +190,7 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
for (size_t i = start_idx; i < batch->used_scans; ++i) {
const int delay = get_delay(batch, i, delays);
- riscv_log_dmi_scan(batch->target, delay, batch->fields + i,
- /*discard_in*/ false);
+ riscv_log_dmi_scan(batch->target, delay, batch->fields + i);
}
batch->was_run = true;
@@ -199,14 +198,14 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
return ERROR_OK;
}
-void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
+void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
bool read_back, enum riscv_scan_delay_class delay_class)
{
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
field->num_bits = riscv_get_dmi_scan_length(batch->target);
field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
- riscv_fill_dm_write(batch->target, (char *)field->out_value, address, data);
+ riscv_fill_dmi_write(batch->target, (char *)field->out_value, address, data);
if (read_back) {
field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
riscv_fill_dm_nop(batch->target, (char *)field->in_value);
@@ -218,7 +217,7 @@ void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint3
batch->used_scans++;
}
-size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
+size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint64_t address,
enum riscv_scan_delay_class delay_class)
{
assert(batch->used_scans < batch->allocated_scans);
@@ -226,7 +225,7 @@ size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
field->num_bits = riscv_get_dmi_scan_length(batch->target);
field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
- riscv_fill_dm_read(batch->target, (char *)field->out_value, address);
+ riscv_fill_dmi_read(batch->target, (char *)field->out_value, address);
riscv_fill_dm_nop(batch->target, (char *)field->in_value);
batch->delay_classes[batch->used_scans] = delay_class;
batch->last_scan = RISCV_SCAN_TYPE_READ;
diff --git a/src/target/riscv/batch.h b/src/target/riscv/batch.h
index 327406c..660a63f 100644
--- a/src/target/riscv/batch.h
+++ b/src/target/riscv/batch.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__SCANS_H
-#define TARGET__RISCV__SCANS_H
+#ifndef OPENOCD_TARGET_RISCV_BATCH_H
+#define OPENOCD_TARGET_RISCV_BATCH_H
#include "target/target.h"
#include "jtag/jtag.h"
@@ -190,14 +190,32 @@ int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
size_t riscv_batch_finished_scans(const struct riscv_batch *batch);
/* Adds a DM register write to this batch. */
-void riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
+void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
bool read_back, enum riscv_scan_delay_class delay_class);
+static inline void
+riscv_batch_add_dm_write(struct riscv_batch *batch, uint64_t address, uint32_t data,
+ bool read_back, enum riscv_scan_delay_class delay_type)
+{
+ return riscv_batch_add_dmi_write(batch,
+ riscv_get_dmi_address(batch->target, address), data,
+ read_back, delay_type);
+}
+
/* DM register reads must be handled in two parts: the first one schedules a read and
* provides a key, the second one actually obtains the result of the read -
* status (op) and the actual data. */
-size_t riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
+size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint64_t address,
enum riscv_scan_delay_class delay_class);
+
+static inline size_t
+riscv_batch_add_dm_read(struct riscv_batch *batch, uint64_t address,
+ enum riscv_scan_delay_class delay_type)
+{
+ return riscv_batch_add_dmi_read(batch,
+ riscv_get_dmi_address(batch->target, address), delay_type);
+}
+
unsigned int riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key);
uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t key);
@@ -213,7 +231,7 @@ bool riscv_batch_was_batch_busy(const struct riscv_batch *batch);
/* TODO: The function is defined in `riscv-013.c`. This is done to reduce the
* diff of the commit. The intention is to move the function definition to
* a separate module (e.g. `riscv013-jtag-dtm.c/h`) in another commit. */
-void riscv_log_dmi_scan(const struct target *target, int idle, const struct scan_field *field,
- bool discard_in);
+void riscv_log_dmi_scan(const struct target *target, int idle,
+ const struct scan_field *field);
-#endif
+#endif /* OPENOCD_TARGET_RISCV_BATCH_H */
diff --git a/src/target/riscv/debug_reg_printer.h b/src/target/riscv/debug_reg_printer.h
index 98226b7..5089ff8 100644
--- a/src/target/riscv/debug_reg_printer.h
+++ b/src/target/riscv/debug_reg_printer.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef OPENOCD_TARGET_RISCV_DEBUG_REG_PRINTER_H
+#define OPENOCD_TARGET_RISCV_DEBUG_REG_PRINTER_H
+
#include "debug_defines.h"
enum riscv_debug_reg_show {
@@ -33,3 +36,5 @@ enum riscv_debug_reg_show {
unsigned int riscv_debug_reg_to_s(char *buf, enum riscv_debug_reg_ordinal reg_ordinal,
riscv_debug_reg_ctx_t context, uint64_t value,
enum riscv_debug_reg_show show);
+
+#endif /* OPENOCD_TARGET_RISCV_DEBUG_REG_PRINTER_H */
diff --git a/src/target/riscv/field_helpers.h b/src/target/riscv/field_helpers.h
index 16578f1..abf19f6 100644
--- a/src/target/riscv/field_helpers.h
+++ b/src/target/riscv/field_helpers.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef FIELD_HELPERS_H
-#define FIELD_HELPERS_H
+#ifndef OPENOCD_TARGET_RISCV_FIELD_HELPERS_H
+#define OPENOCD_TARGET_RISCV_FIELD_HELPERS_H
#include <stdint.h>
#include <assert.h>
@@ -44,4 +44,4 @@ static inline uint32_t field_value32(uint32_t mask, uint32_t val)
return set_field32(0, mask, val);
}
-#endif
+#endif /* OPENOCD_TARGET_RISCV_FIELD_HELPERS_H */
diff --git a/src/target/riscv/gdb_regs.h b/src/target/riscv/gdb_regs.h
index d606f73..0d03929 100644
--- a/src/target/riscv/gdb_regs.h
+++ b/src/target/riscv/gdb_regs.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__GDB_REGS_H
-#define TARGET__RISCV__GDB_REGS_H
+#ifndef OPENOCD_TARGET_RISCV_GDB_REGS_H
+#define OPENOCD_TARGET_RISCV_GDB_REGS_H
#include "encoding.h"
@@ -125,4 +125,4 @@ enum gdb_regno {
GDB_REGNO_COUNT
};
-#endif
+#endif /* OPENOCD_TARGET_RISCV_GDB_REGS_H */
diff --git a/src/target/riscv/opcodes.h b/src/target/riscv/opcodes.h
index 59c3413..99ae90f 100644
--- a/src/target/riscv/opcodes.h
+++ b/src/target/riscv/opcodes.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef OPENOCD_TARGET_RISCV_OPCODES_H
+#define OPENOCD_TARGET_RISCV_OPCODES_H
+
#include "encoding.h"
#define ZERO 0
@@ -339,3 +342,4 @@ static uint32_t vslide1down_vx(unsigned int vd, unsigned int vs2,
return ((vm & 1) << 25) | inst_rs2(vs2) | inst_rs1(rs1) | inst_rd(vd) | MATCH_VSLIDE1DOWN_VX;
}
+#endif /* OPENOCD_TARGET_RISCV_OPCODES_H */
diff --git a/src/target/riscv/program.c b/src/target/riscv/program.c
index c4ffb3f..85c3d16 100644
--- a/src/target/riscv/program.c
+++ b/src/target/riscv/program.c
@@ -183,8 +183,8 @@ int riscv_program_ebreak(struct riscv_program *p)
{
struct target *target = p->target;
RISCV_INFO(r);
- if (p->instruction_count == riscv_progbuf_size(p->target) &&
- r->impebreak) {
+ if (p->instruction_count == riscv_progbuf_size(target) &&
+ r->get_impebreak(target)) {
return ERROR_OK;
}
return riscv_program_insert(p, ebreak());
diff --git a/src/target/riscv/program.h b/src/target/riscv/program.h
index 93dbdbf..91f0dab 100644
--- a/src/target/riscv/program.h
+++ b/src/target/riscv/program.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__PROGRAM_H
-#define TARGET__RISCV__PROGRAM_H
+#ifndef OPENOCD_TARGET_RISCV_PROGRAM_H
+#define OPENOCD_TARGET_RISCV_PROGRAM_H
#include "riscv.h"
@@ -77,4 +77,4 @@ int riscv_program_ebreak(struct riscv_program *p);
int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t i);
-#endif
+#endif /* OPENOCD_TARGET_RISCV_PROGRAM_H */
diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c
index 0715de5..1da7182 100644
--- a/src/target/riscv/riscv-011.c
+++ b/src/target/riscv/riscv-011.c
@@ -273,38 +273,6 @@ static uint16_t dram_address(unsigned int index)
return 0x40 + index - 0x10;
}
-static int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr)
-{
- struct scan_field field;
- uint8_t in_value[4];
- uint8_t out_value[4] = { 0 };
-
- buf_set_u32(out_value, 0, 32, out);
-
- jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);
-
- field.num_bits = 32;
- field.out_value = out_value;
- field.in_value = in_value;
- jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
-
- /* Always return to dbus. */
- jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
-
- int retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("failed jtag scan: %d", retval);
- return retval;
- }
-
- uint32_t in = buf_get_u32(field.in_value, 0, 32);
- LOG_DEBUG("DTMCONTROL: 0x%x -> 0x%x", out, in);
-
- if (in_ptr)
- *in_ptr = in;
- return ERROR_OK;
-}
-
static uint32_t idcode_scan(struct target *target)
{
struct scan_field field;
@@ -408,7 +376,7 @@ static void dump_field(const struct scan_field *field)
log_printf_lf(LOG_LVL_DEBUG,
__FILE__, __LINE__, "scan",
- "%db %s %c%c:%08x @%02x -> %s %c%c:%08x @%02x",
+ "%ub %s %c%c:%08x @%02x -> %s %c%c:%08x @%02x",
field->num_bits,
op_string[out_op], out_interrupt, out_haltnot, out_data,
out_address,
@@ -2388,6 +2356,16 @@ static int riscv011_authdata_write(struct target *target, uint32_t value, unsign
return ERROR_OK;
}
+static bool riscv011_get_impebreak(const struct target *target)
+{
+ return false;
+}
+
+static unsigned int riscv011_get_progbufsize(const struct target *target)
+{
+ return 0;
+}
+
static int init_target(struct command_context *cmd_ctx,
struct target *target)
{
@@ -2397,6 +2375,8 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->authdata_read = &riscv011_authdata_read;
generic_info->authdata_write = &riscv011_authdata_write;
generic_info->print_info = &riscv011_print_info;
+ generic_info->get_impebreak = &riscv011_get_impebreak;
+ generic_info->get_progbufsize = &riscv011_get_progbufsize;
generic_info->version_specific = calloc(1, sizeof(riscv011_info_t));
if (!generic_info->version_specific)
diff --git a/src/target/riscv/riscv-011.h b/src/target/riscv/riscv-011.h
index 8d1d06a..bbbc194 100644
--- a/src/target/riscv/riscv-011.h
+++ b/src/target/riscv/riscv-011.h
@@ -12,4 +12,4 @@ int riscv011_get_register(struct target *target, riscv_reg_t *value,
int riscv011_set_register(struct target *target, enum gdb_regno regid,
riscv_reg_t value);
-#endif /*OPENOCD_TARGET_RISCV_RISCV_011_H*/
+#endif /* OPENOCD_TARGET_RISCV_RISCV_011_H */
diff --git a/src/target/riscv/riscv-011_reg.c b/src/target/riscv/riscv-011_reg.c
index 7f29064..44ea1a4 100644
--- a/src/target/riscv/riscv-011_reg.c
+++ b/src/target/riscv/riscv-011_reg.c
@@ -38,7 +38,9 @@ static const struct reg_arch_type *riscv011_gdb_regno_reg_type(uint32_t regno)
static int riscv011_init_reg(struct target *target, uint32_t regno)
{
- return riscv_reg_impl_init_one(target, regno, riscv011_gdb_regno_reg_type(regno));
+ return riscv_reg_impl_init_cache_entry(target, regno,
+ riscv_reg_impl_gdb_regno_exist(target, regno),
+ riscv011_gdb_regno_reg_type(regno));
}
int riscv011_reg_init_all(struct target *target)
diff --git a/src/target/riscv/riscv-011_reg.h b/src/target/riscv/riscv-011_reg.h
index ee00c9b..4f7911a 100644
--- a/src/target/riscv/riscv-011_reg.h
+++ b/src/target/riscv/riscv-011_reg.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef OPENOCD_TARGET_RISCV_RISCV_REG_011_H
-#define OPENOCD_TARGET_RISCV_RISCV_REG_011_H
+#ifndef OPENOCD_TARGET_RISCV_RISCV_011_REG_H
+#define OPENOCD_TARGET_RISCV_RISCV_011_REG_H
#include "target/target.h"
@@ -16,4 +16,4 @@
*/
int riscv011_reg_init_all(struct target *target);
-#endif /*OPENOCD_TARGET_RISCV_RISCV_REG_011_H*/
+#endif /* OPENOCD_TARGET_RISCV_RISCV_011_REG_H */
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 7898cae..f2c4676 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -16,6 +16,7 @@
#include "target/target.h"
#include "target/algorithm.h"
#include "target/target_type.h"
+#include <helper/align.h>
#include <helper/log.h>
#include "jtag/jtag.h"
#include "target/register.h"
@@ -56,10 +57,7 @@ static int riscv013_invalidate_cached_progbuf(struct target *target);
static int riscv013_execute_progbuf(struct target *target, uint32_t *cmderr);
static void riscv013_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d);
static void riscv013_fill_dmi_read(struct target *target, char *buf, uint64_t a);
-static void riscv013_fill_dmi_nop(struct target *target, char *buf);
static int riscv013_get_dmi_scan_length(struct target *target);
-static void riscv013_fill_dm_write(struct target *target, char *buf, uint64_t a, uint32_t d);
-static void riscv013_fill_dm_read(struct target *target, char *buf, uint64_t a);
static void riscv013_fill_dm_nop(struct target *target, char *buf);
static unsigned int register_size(struct target *target, enum gdb_regno number);
static int register_read_direct(struct target *target, riscv_reg_t *value,
@@ -70,6 +68,8 @@ static int read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment);
static int write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
+static bool riscv013_get_impebreak(const struct target *target);
+static unsigned int riscv013_get_progbufsize(const struct target *target);
typedef enum {
HALT_GROUP,
@@ -115,7 +115,7 @@ typedef enum {
typedef struct {
struct list_head list;
- int abs_chain_position;
+ unsigned int abs_chain_position;
/* The base address to access this DM on DMI */
uint32_t base;
/* The number of harts connected to this DM. */
@@ -156,7 +156,9 @@ typedef struct {
/* Number of abstract command data registers. */
unsigned datacount;
/* Number of words in the Program Buffer. */
- unsigned progbufsize;
+ unsigned int progbufsize;
+ /* Hart contains an implicit ebreak at the end of the program buffer. */
+ bool impebreak;
/* We cache the read-only bits of sbcs here. */
uint32_t sbcs;
@@ -223,7 +225,7 @@ static dm013_info_t *get_dm(struct target *target)
if (info->dm)
return info->dm;
- int abs_chain_position = target->tap->abs_chain_position;
+ unsigned int abs_chain_position = target->tap->abs_chain_position;
dm013_info_t *entry;
dm013_info_t *dm = NULL;
@@ -376,7 +378,9 @@ static unsigned int decode_dmi(const struct target *target, char *text, uint32_t
return 0;
}
-void riscv_log_dmi_scan(const struct target *target, int idle, const struct scan_field *field, bool discard_in)
+/* TODO: Move this function to "batch.c" and make it static. */
+void riscv_log_dmi_scan(const struct target *target, int idle,
+ const struct scan_field *field)
{
static const char * const op_string[] = {"-", "r", "w", "?"};
static const char * const status_string[] = {"+", "?", "F", "b"};
@@ -400,7 +404,7 @@ void riscv_log_dmi_scan(const struct target *target, int idle, const struct scan
field->num_bits, op_string[out_op], out_data, out_address,
status_string[in_op], in_data, in_address, idle);
- if (!discard_in && in_op == DTM_DMI_OP_SUCCESS) {
+ if (in_op == DTM_DMI_OP_SUCCESS) {
char in_decoded[decode_dmi(target, NULL, in_address, in_data) + 1];
decode_dmi(target, in_decoded, in_address, in_data);
/* FIXME: The current code assumes that the hardware
@@ -431,44 +435,12 @@ static void select_dmi(struct target *target)
select_dmi_via_bscan(target);
return;
}
+ if (buf_cmp(target->tap->cur_instr, select_dbus.out_value,
+ target->tap->ir_length) == 0)
+ return;
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
}
-static int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr)
-{
- struct scan_field field;
- uint8_t in_value[4];
- uint8_t out_value[4] = { 0 };
-
- if (bscan_tunnel_ir_width != 0)
- return dtmcontrol_scan_via_bscan(target, out, in_ptr);
-
- buf_set_u32(out_value, 0, 32, out);
-
- jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);
-
- field.num_bits = 32;
- field.out_value = out_value;
- field.in_value = in_value;
- jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
-
- /* Always return to dmi. */
- select_dmi(target);
-
- int retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("failed jtag scan: %d", retval);
- return retval;
- }
-
- uint32_t in = buf_get_u32(field.in_value, 0, 32);
- LOG_DEBUG("DTMCS: 0x%x -> 0x%x", out, in);
-
- if (in_ptr)
- *in_ptr = in;
- return ERROR_OK;
-}
-
static int increase_dmi_busy_delay(struct target *target)
{
RISCV013_INFO(info);
@@ -506,220 +478,6 @@ static void decrement_reset_delays_counter(struct target *target, size_t finishe
"resetting learned delays (reset_delays_wait counter expired)");
reset_learned_delays(target);
}
-/**
- * exec: If this is set, assume the scan results in an execution, so more
- * run-test/idle cycles may be required.
- */
-static dmi_status_t dmi_scan(struct target *target, uint32_t *address_in,
- uint32_t *data_in, dmi_op_t op, uint32_t address_out, uint32_t data_out,
- bool exec)
-{
- riscv013_info_t *info = get_info(target);
- unsigned num_bits = info->abits + DTM_DMI_OP_LENGTH + DTM_DMI_DATA_LENGTH;
- size_t num_bytes = (num_bits + 7) / 8;
- uint8_t in[num_bytes];
- uint8_t out[num_bytes];
- struct scan_field field = {
- .num_bits = num_bits,
- .out_value = out,
- .in_value = in
- };
- riscv_bscan_tunneled_scan_context_t bscan_ctxt;
-
- decrement_reset_delays_counter(target, 1);
-
- memset(in, 0, num_bytes);
- memset(out, 0, num_bytes);
-
- if (info->abits == 0) {
- LOG_TARGET_ERROR(target, "Can't access DMI because addrbits=0.");
- return DMI_STATUS_FAILED;
- }
-
- buf_set_u32(out, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, op);
- buf_set_u32(out, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH, data_out);
- buf_set_u32(out, DTM_DMI_ADDRESS_OFFSET, info->abits, address_out);
-
- /* I wanted to place this code in a different function, but the way JTAG command
- queueing works in the jtag handling functions, the scan fields either have to be
- heap allocated, global/static, or else they need to stay on the stack until
- the jtag_execute_queue() call. Heap or static fields in this case doesn't seem
- the best fit. Declaring stack based field values in a subsidiary function call wouldn't
- work. */
- if (bscan_tunnel_ir_width != 0) {
- riscv_add_bscan_tunneled_scan(target, &field, &bscan_ctxt);
- } else {
- /* Assume dbus is already selected. */
- jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
- }
-
- int idle_count = exec
- ? riscv_scan_get_delay(&info->learned_delays, RISCV_DELAY_ABSTRACT_COMMAND)
- : riscv_scan_get_delay(&info->learned_delays, RISCV_DELAY_BASE);
-
- if (idle_count)
- jtag_add_runtest(idle_count, TAP_IDLE);
-
- int retval = jtag_execute_queue();
- if (retval != ERROR_OK) {
- LOG_ERROR("dmi_scan failed jtag scan");
- if (data_in)
- *data_in = ~0;
- return DMI_STATUS_FAILED;
- }
-
- if (bscan_tunnel_ir_width != 0) {
- /* need to right-shift "in" by one bit, because of clock skew between BSCAN TAP and DM TAP */
- buffer_shr(in, num_bytes, 1);
- }
-
- if (data_in)
- *data_in = buf_get_u32(in, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH);
-
- if (address_in)
- *address_in = buf_get_u32(in, DTM_DMI_ADDRESS_OFFSET, info->abits);
- riscv_log_dmi_scan(target, idle_count, &field, /*discard_in*/ !data_in);
- return buf_get_u32(in, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH);
-}
-
-/**
- * @param target
- * @param data_in The data we received from the target.
- * @param dmi_busy_encountered
- * If non-NULL, will be updated to reflect whether DMI busy was
- * encountered while executing this operation or not.
- * @param op The operation to perform (read/write/nop).
- * @param address The address argument to that operation.
- * @param data_out The data to send to the target.
- * @param timeout_sec
- * @param exec When true, this scan will execute something, so extra RTI
- * cycles may be added.
- * @param ensure_success
- * Scan a nop after the requested operation, ensuring the
- * DMI operation succeeded.
- */
-static int dmi_op_timeout(struct target *target, uint32_t *data_in,
- bool *dmi_busy_encountered, int op, uint32_t address,
- uint32_t data_out, int timeout_sec, bool exec, bool ensure_success)
-{
- select_dmi(target);
-
- dmi_status_t status;
-
- if (dmi_busy_encountered)
- *dmi_busy_encountered = false;
-
- const char *op_name;
- switch (op) {
- case DMI_OP_NOP:
- op_name = "nop";
- break;
- case DMI_OP_READ:
- op_name = "read";
- break;
- case DMI_OP_WRITE:
- op_name = "write";
- break;
- default:
- LOG_ERROR("Invalid DMI operation: %d", op);
- return ERROR_FAIL;
- }
-
- keep_alive();
-
- time_t start = time(NULL);
- /* This first loop performs the request. Note that if for some reason this
- * stays busy, it is actually due to the previous access. */
- while (1) {
- status = dmi_scan(target, NULL, NULL, op, address, data_out,
- exec);
- if (status == DMI_STATUS_BUSY) {
- int result = increase_dmi_busy_delay(target);
- if (result != ERROR_OK)
- return result;
- if (dmi_busy_encountered)
- *dmi_busy_encountered = true;
- } else if (status == DMI_STATUS_SUCCESS) {
- break;
- } else {
- dtmcontrol_scan(target, DTM_DTMCS_DMIRESET, NULL /* discard result */);
- break;
- }
- if (time(NULL) - start > timeout_sec)
- return ERROR_TIMEOUT_REACHED;
- }
-
- if (status != DMI_STATUS_SUCCESS) {
- LOG_TARGET_ERROR(target, "Failed DMI %s at 0x%x; status=%d", op_name, address, status);
- return ERROR_FAIL;
- }
-
- if (ensure_success) {
- /* This second loop ensures the request succeeded, and gets back data.
- * Note that NOP can result in a 'busy' result as well, but that would be
- * noticed on the next DMI access we do. */
- while (1) {
- status = dmi_scan(target, NULL, data_in, DMI_OP_NOP, address, 0,
- false);
- if (status == DMI_STATUS_BUSY) {
- int result = increase_dmi_busy_delay(target);
- if (result != ERROR_OK)
- return result;
- if (dmi_busy_encountered)
- *dmi_busy_encountered = true;
- } else if (status == DMI_STATUS_SUCCESS) {
- break;
- } else {
- if (data_in) {
- LOG_TARGET_ERROR(target,
- "Failed DMI %s (NOP) at 0x%x; value=0x%x, status=%d",
- op_name, address, *data_in, status);
- } else {
- LOG_TARGET_ERROR(target,
- "Failed DMI %s (NOP) at 0x%x; status=%d", op_name, address,
- status);
- }
- dtmcontrol_scan(target, DTM_DTMCS_DMIRESET, NULL /* discard result */);
- return ERROR_FAIL;
- }
- if (time(NULL) - start > timeout_sec)
- return ERROR_TIMEOUT_REACHED;
- }
- }
-
- return ERROR_OK;
-}
-
-static int dmi_op(struct target *target, uint32_t *data_in,
- bool *dmi_busy_encountered, int op, uint32_t address,
- uint32_t data_out, bool exec, bool ensure_success)
-{
- int result = dmi_op_timeout(target, data_in, dmi_busy_encountered, op,
- address, data_out, riscv_get_command_timeout_sec(), exec, ensure_success);
- if (result == ERROR_TIMEOUT_REACHED) {
- LOG_TARGET_ERROR(target, "DMI operation didn't complete in %d seconds. The target is "
- "either really slow or broken. You could increase the "
- "timeout with riscv set_command_timeout_sec.",
- riscv_get_command_timeout_sec());
- return ERROR_FAIL;
- }
- return result;
-}
-
-static int dmi_read(struct target *target, uint32_t *value, uint32_t address)
-{
- return dmi_op(target, value, NULL, DMI_OP_READ, address, 0, false, true);
-}
-
-static int dmi_read_exec(struct target *target, uint32_t *value, uint32_t address)
-{
- return dmi_op(target, value, NULL, DMI_OP_READ, address, 0, true, true);
-}
-
-static int dmi_write(struct target *target, uint32_t address, uint32_t value)
-{
- return dmi_op(target, NULL, NULL, DMI_OP_WRITE, address, value, false, true);
-}
static uint32_t riscv013_get_dmi_address(const struct target *target, uint32_t address)
{
@@ -731,23 +489,22 @@ static uint32_t riscv013_get_dmi_address(const struct target *target, uint32_t a
return address + base;
}
-static int dm_op(struct target *target, uint32_t *data_in,
- bool *dmi_busy_encountered, int op, uint32_t address,
- uint32_t data_out, bool exec, bool ensure_success)
+static int batch_run_timeout(struct target *target, struct riscv_batch *batch);
+
+static int dmi_read(struct target *target, uint32_t *value, uint32_t address)
{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return ERROR_FAIL;
- return dmi_op(target, data_in, dmi_busy_encountered, op, address + dm->base,
- data_out, exec, ensure_success);
+ struct riscv_batch *batch = riscv_batch_alloc(target, 1);
+ riscv_batch_add_dmi_read(batch, address, RISCV_DELAY_BASE);
+ int res = batch_run_timeout(target, batch);
+ if (res == ERROR_OK && value)
+ *value = riscv_batch_get_dmi_read_data(batch, 0);
+ riscv_batch_free(batch);
+ return res;
}
static int dm_read(struct target *target, uint32_t *value, uint32_t address)
{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return ERROR_FAIL;
- return dmi_read(target, value, address + dm->base);
+ return dmi_read(target, value, riscv013_get_dmi_address(target, address));
}
static int dm_read_exec(struct target *target, uint32_t *value, uint32_t address)
@@ -755,16 +512,29 @@ static int dm_read_exec(struct target *target, uint32_t *value, uint32_t address
dm013_info_t *dm = get_dm(target);
if (!dm)
return ERROR_FAIL;
+ struct riscv_batch *batch = riscv_batch_alloc(target, 1);
+ riscv_batch_add_dm_read(batch, address, RISCV_DELAY_ABSTRACT_COMMAND);
dm->abstract_cmd_maybe_busy = true;
- return dmi_read_exec(target, value, address + dm->base);
+ int res = batch_run_timeout(target, batch);
+ if (res == ERROR_OK && value)
+ *value = riscv_batch_get_dmi_read_data(batch, 0);
+ riscv_batch_free(batch);
+ return res;
+}
+
+static int dmi_write(struct target *target, uint32_t address, uint32_t value)
+{
+ struct riscv_batch *batch = riscv_batch_alloc(target, 1);
+ riscv_batch_add_dmi_write(batch, address, value, /*read_back*/ true,
+ RISCV_DELAY_BASE);
+ int res = batch_run_timeout(target, batch);
+ riscv_batch_free(batch);
+ return res;
}
static int dm_write(struct target *target, uint32_t address, uint32_t value)
{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return ERROR_FAIL;
- return dmi_write(target, address + dm->base, value);
+ return dmi_write(target, riscv013_get_dmi_address(target, address), value);
}
static bool check_dbgbase_exists(struct target *target)
@@ -930,9 +700,7 @@ clear_cmderr:
return res;
}
-static int batch_run_timeout(struct target *target, struct riscv_batch *batch);
-
-static int execute_abstract_command(struct target *target, uint32_t command,
+int riscv013_execute_abstract_command(struct target *target, uint32_t command,
uint32_t *cmderr)
{
assert(cmderr);
@@ -1068,7 +836,7 @@ static int write_abstract_arg(struct target *target, unsigned index,
/**
* @par size in bits
*/
-static uint32_t access_register_command(struct target *target, uint32_t number,
+uint32_t riscv013_access_register_command(struct target *target, uint32_t number,
unsigned size, uint32_t flags)
{
uint32_t command = set_field(0, DM_COMMAND_CMDTYPE, 0);
@@ -1125,11 +893,11 @@ static int register_read_abstract_with_size(struct target *target,
if (number >= GDB_REGNO_V0 && number <= GDB_REGNO_V31)
return ERROR_FAIL;
- uint32_t command = access_register_command(target, number, size,
+ uint32_t command = riscv013_access_register_command(target, number, size,
AC_ACCESS_REGISTER_TRANSFER);
uint32_t cmderr;
- int result = execute_abstract_command(target, command, &cmderr);
+ int result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result != ERROR_OK) {
if (cmderr == CMDERR_NOT_SUPPORTED) {
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
@@ -1174,7 +942,7 @@ static int register_write_abstract(struct target *target, enum gdb_regno number,
return ERROR_FAIL;
const unsigned int size_bits = register_size(target, number);
- const uint32_t command = access_register_command(target, number, size_bits,
+ const uint32_t command = riscv013_access_register_command(target, number, size_bits,
AC_ACCESS_REGISTER_TRANSFER |
AC_ACCESS_REGISTER_WRITE);
LOG_DEBUG_REG(target, AC_ACCESS_REGISTER, command);
@@ -1550,9 +1318,7 @@ static unsigned int register_size(struct target *target, enum gdb_regno number)
static bool has_sufficient_progbuf(struct target *target, unsigned size)
{
RISCV013_INFO(info);
- RISCV_INFO(r);
-
- return info->progbufsize + r->impebreak >= size;
+ return info->progbufsize + info->impebreak >= size;
}
/**
@@ -2277,14 +2043,13 @@ static int examine(struct target *target)
LOG_TARGET_INFO(target, "datacount=%d progbufsize=%d",
info->datacount, info->progbufsize);
- RISCV_INFO(r);
- r->impebreak = get_field(dmstatus, DM_DMSTATUS_IMPEBREAK);
+ info->impebreak = get_field(dmstatus, DM_DMSTATUS_IMPEBREAK);
if (!has_sufficient_progbuf(target, 2)) {
LOG_TARGET_WARNING(target, "We won't be able to execute fence instructions on this "
"target. Memory may not always appear consistent. "
"(progbufsize=%d, impebreak=%d)", info->progbufsize,
- r->impebreak);
+ info->impebreak);
}
if (info->progbufsize < 4 && riscv_enable_virtual) {
@@ -2300,6 +2065,8 @@ static int examine(struct target *target)
enum riscv_hart_state state_at_examine_start;
if (riscv_get_hart_state(target, &state_at_examine_start) != ERROR_OK)
return ERROR_FAIL;
+
+ RISCV_INFO(r);
const bool hart_halted_at_examine_start = state_at_examine_start == RISCV_STATE_HALTED;
if (!hart_halted_at_examine_start) {
r->prepped = true;
@@ -2313,74 +2080,9 @@ static int examine(struct target *target)
target->state = TARGET_HALTED;
target->debug_reason = hart_halted_at_examine_start ? DBG_REASON_UNDEFINED : DBG_REASON_DBGRQ;
- /* Without knowing anything else we can at least mess with the
- * program buffer. */
- r->progbuf_size = info->progbufsize;
-
- result = register_read_abstract_with_size(target, NULL, GDB_REGNO_S0, 64);
- if (result == ERROR_OK)
- r->xlen = 64;
- else
- r->xlen = 32;
-
- /* Save s0 and s1. The register cache hasn't be initialized yet so we
- * need to take care of this manually. */
- uint64_t s0, s1;
- if (register_read_abstract(target, &s0, GDB_REGNO_S0) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to read s0.");
- return ERROR_FAIL;
- }
- if (register_read_abstract(target, &s1, GDB_REGNO_S1) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to read s1.");
- return ERROR_FAIL;
- }
-
- if (register_read_direct(target, &r->misa, GDB_REGNO_MISA)) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to read MISA.");
- return ERROR_FAIL;
- }
-
- uint64_t value;
- if (register_read_direct(target, &value, GDB_REGNO_VLENB) != ERROR_OK) {
- if (riscv_supports_extension(target, 'V'))
- LOG_TARGET_WARNING(target, "Couldn't read vlenb; vector register access won't work.");
- r->vlenb = 0;
- } else {
- r->vlenb = value;
- LOG_TARGET_INFO(target, "Vector support with vlenb=%d", r->vlenb);
- }
-
- if (register_read_direct(target, &value, GDB_REGNO_MTOPI) == ERROR_OK) {
- r->mtopi_readable = true;
-
- if (register_read_direct(target, &value, GDB_REGNO_MTOPEI) == ERROR_OK) {
- LOG_TARGET_INFO(target, "S?aia detected with IMSIC");
- r->mtopei_readable = true;
- } else {
- r->mtopei_readable = false;
- LOG_TARGET_INFO(target, "S?aia detected without IMSIC");
- }
- } else {
- r->mtopi_readable = false;
- }
-
- /* Display this as early as possible to help people who are using
- * really slow simulators. */
- LOG_TARGET_DEBUG(target, " XLEN=%d, misa=0x%" PRIx64, r->xlen, r->misa);
-
- /* Restore s0 and s1. */
- if (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to write back s0.");
- return ERROR_FAIL;
- }
- if (register_write_direct(target, GDB_REGNO_S1, s1) != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Fatal: Failed to write back s1.");
- return ERROR_FAIL;
- }
-
- /* Now init registers based on what we discovered. */
- if (riscv013_reg_init_all(target) != ERROR_OK)
- return ERROR_FAIL;
+ result = riscv013_reg_examine_all(target);
+ if (result != ERROR_OK)
+ return result;
if (set_dcsr_ebreak(target, false) != ERROR_OK)
return ERROR_FAIL;
@@ -2716,21 +2418,42 @@ static uint32_t sb_sbaccess(unsigned int size_bytes)
return 0;
}
-static int sb_write_address(struct target *target, target_addr_t address,
- bool ensure_success)
+static unsigned int get_sbaadress_reg_count(const struct target *target)
{
RISCV013_INFO(info);
- unsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);
+ const unsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);
+ return DIV_ROUND_UP(sbasize, 32);
+}
+
+static void batch_fill_sb_write_address(const struct target *target,
+ struct riscv_batch *batch, target_addr_t address,
+ enum riscv_scan_delay_class sbaddr0_delay)
+{
/* There currently is no support for >64-bit addresses in OpenOCD. */
- if (sbasize > 96)
- dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS3, 0, false, false);
- if (sbasize > 64)
- dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS2, 0, false, false);
- if (sbasize > 32)
- dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS1,
- (uint32_t)(address >> 32), false, false);
- return dm_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS0,
- (uint32_t)address, false, ensure_success);
+ assert(sizeof(target_addr_t) == sizeof(uint64_t));
+ const uint32_t addresses[] = {DM_SBADDRESS0, DM_SBADDRESS1, DM_SBADDRESS2, DM_SBADDRESS3};
+ const uint32_t values[] = {(uint32_t)address, (uint32_t)(address >> 32), 0, 0};
+ const unsigned int reg_count = get_sbaadress_reg_count(target);
+ assert(reg_count > 0);
+ assert(reg_count <= ARRAY_SIZE(addresses));
+ assert(ARRAY_SIZE(addresses) == ARRAY_SIZE(values));
+
+ for (unsigned int i = reg_count - 1; i > 0; --i)
+ riscv_batch_add_dm_write(batch, addresses[i], values[i], /* read back */ true,
+ RISCV_DELAY_BASE);
+ riscv_batch_add_dm_write(batch, addresses[0], values[0], /* read back */ true,
+ sbaddr0_delay);
+}
+
+static int sb_write_address(struct target *target, target_addr_t address,
+ enum riscv_scan_delay_class sbaddr0_delay)
+{
+ struct riscv_batch *batch = riscv_batch_alloc(target,
+ get_sbaadress_reg_count(target));
+ batch_fill_sb_write_address(target, batch, address, sbaddr0_delay);
+ const int res = batch_run_timeout(target, batch);
+ riscv_batch_free(batch);
+ return res;
}
static int batch_run(struct target *target, struct riscv_batch *batch)
@@ -3085,8 +2808,8 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->write_progbuf = &riscv013_write_progbuf;
generic_info->execute_progbuf = &riscv013_execute_progbuf;
generic_info->invalidate_cached_progbuf = &riscv013_invalidate_cached_progbuf;
- generic_info->fill_dm_write = &riscv013_fill_dm_write;
- generic_info->fill_dm_read = &riscv013_fill_dm_read;
+ generic_info->fill_dmi_write = &riscv013_fill_dmi_write;
+ generic_info->fill_dmi_read = &riscv013_fill_dmi_read;
generic_info->fill_dm_nop = &riscv013_fill_dm_nop;
generic_info->get_dmi_scan_length = &riscv013_get_dmi_scan_length;
generic_info->authdata_read = &riscv013_authdata_read;
@@ -3097,6 +2820,8 @@ static int init_target(struct command_context *cmd_ctx,
generic_info->read_memory = read_memory;
generic_info->data_bits = &riscv013_data_bits;
generic_info->print_info = &riscv013_print_info;
+ generic_info->get_impebreak = &riscv013_get_impebreak;
+ generic_info->get_progbufsize = &riscv013_get_progbufsize;
generic_info->handle_became_unavailable = &handle_became_unavailable;
generic_info->tick = &tick;
@@ -3533,6 +3258,9 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
return ERROR_NOT_IMPLEMENTED;
}
+ assert(size <= 16);
+ assert(IS_PWR_OF_2(size));
+
dm013_info_t *dm = get_dm(target);
if (!dm)
return ERROR_FAIL;
@@ -3555,21 +3283,9 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
return ERROR_FAIL;
/* This address write will trigger the first read. */
- if (sb_write_address(target, next_address, true) != ERROR_OK)
+ if (sb_write_address(target, next_address, RISCV_DELAY_SYSBUS_READ) != ERROR_OK)
return ERROR_FAIL;
- unsigned int bus_master_read_delay = riscv_scan_get_delay(&info->learned_delays,
- RISCV_DELAY_SYSBUS_READ);
- if (bus_master_read_delay) {
- LOG_TARGET_DEBUG(target, "Waiting %d cycles for bus master read delay",
- bus_master_read_delay);
- jtag_add_runtest(bus_master_read_delay, TAP_IDLE);
- if (jtag_execute_queue() != ERROR_OK) {
- LOG_TARGET_ERROR(target, "Failed to scan idle sequence");
- return ERROR_FAIL;
- }
- }
-
/* First read has been started. Optimistically assume that it has
* completed. */
@@ -3580,7 +3296,6 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
* be unnecessary.
*/
uint32_t sbvalue[4] = {0};
- assert(size <= 16);
for (uint32_t i = (next_address - address) / size; i < count - 1; i++) {
const uint32_t size_in_words = DIV_ROUND_UP(size, 4);
struct riscv_batch *batch = riscv_batch_alloc(target, size_in_words);
@@ -3601,10 +3316,10 @@ static int read_memory_bus_v1(struct target *target, target_addr_t address,
const size_t last_key = batch->read_keys_used - 1;
for (size_t k = 0; k <= last_key; ++k) {
- sbvalue[k] = riscv_batch_get_dmi_read_data(batch,
- last_key - k);
- buf_set_u32(buffer + i * size + k * 4, 0, 8 * size, sbvalue[k]);
+ sbvalue[k] = riscv_batch_get_dmi_read_data(batch, last_key - k);
+ buf_set_u32(buffer + i * size + k * 4, 0, MIN(32, 8 * size), sbvalue[k]);
}
+
riscv_batch_free(batch);
const target_addr_t read_addr = address + i * increment;
log_memory_access(read_addr, sbvalue, size, true);
@@ -3847,7 +3562,7 @@ static int read_memory_abstract(struct target *target, target_addr_t address,
/* Execute the command */
uint32_t cmderr;
- result = execute_abstract_command(target, command, &cmderr);
+ result = riscv013_execute_abstract_command(target, command, &cmderr);
/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
@@ -3869,7 +3584,7 @@ static int read_memory_abstract(struct target *target, target_addr_t address,
} else {
/* Try the same access but with postincrement disabled. */
command = access_memory_command(target, false, width, false, false);
- result = execute_abstract_command(target, command, &cmderr);
+ result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result == ERROR_OK) {
LOG_TARGET_DEBUG(target, "aampostincrement is not supported on this target.");
info->has_aampostincrement = YNM_NO;
@@ -3940,7 +3655,7 @@ static int write_memory_abstract(struct target *target, target_addr_t address,
/* Execute the command */
uint32_t cmderr;
- result = execute_abstract_command(target, command, &cmderr);
+ result = riscv013_execute_abstract_command(target, command, &cmderr);
/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
@@ -3962,7 +3677,7 @@ static int write_memory_abstract(struct target *target, target_addr_t address,
} else {
/* Try the same access but with postincrement disabled. */
command = access_memory_command(target, false, width, false, true);
- result = execute_abstract_command(target, command, &cmderr);
+ result = riscv013_execute_abstract_command(target, command, &cmderr);
if (result == ERROR_OK) {
LOG_TARGET_DEBUG(target, "aampostincrement is not supported on this target.");
info->has_aampostincrement = YNM_NO;
@@ -4008,11 +3723,11 @@ static int read_memory_progbuf_inner_startup(struct target *target,
/* AC_ACCESS_REGISTER_POSTEXEC is used to trigger first stage of the
* pipeline (memory -> s1) whenever this command is executed.
*/
- const uint32_t startup_command = access_register_command(target,
+ const uint32_t startup_command = riscv013_access_register_command(target,
GDB_REGNO_S1, riscv_xlen(target),
AC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC);
uint32_t cmderr;
- if (execute_abstract_command(target, startup_command, &cmderr) != ERROR_OK)
+ if (riscv013_execute_abstract_command(target, startup_command, &cmderr) != ERROR_OK)
return ERROR_FAIL;
/* TODO: we need to modify error handling here. */
/* NOTE: in case of timeout cmderr is set to CMDERR_NONE */
@@ -4495,11 +4210,11 @@ static int read_memory_progbuf_inner_one(struct target *target,
if (write_abstract_arg(target, 0, access.target_address, riscv_xlen(target))
!= ERROR_OK)
return ERROR_FAIL;
- uint32_t command = access_register_command(target, GDB_REGNO_S1,
+ uint32_t command = riscv013_access_register_command(target, GDB_REGNO_S1,
riscv_xlen(target), AC_ACCESS_REGISTER_WRITE |
AC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC);
uint32_t cmderr;
- if (execute_abstract_command(target, command, &cmderr) != ERROR_OK)
+ if (riscv013_execute_abstract_command(target, command, &cmderr) != ERROR_OK)
return ERROR_FAIL;
return read_word_from_s1(target, access, 0);
@@ -4681,9 +4396,10 @@ static int write_memory_bus_v1(struct target *target, target_addr_t address,
target_addr_t next_address = address;
target_addr_t end_address = address + count * size;
- int result;
+ int result = sb_write_address(target, next_address, RISCV_DELAY_BASE);
+ if (result != ERROR_OK)
+ return result;
- sb_write_address(target, next_address, true);
while (next_address < end_address) {
LOG_TARGET_DEBUG(target, "Transferring burst starting at address 0x%" TARGET_PRIxADDR,
next_address);
@@ -4837,14 +4553,14 @@ static int write_memory_progbuf_startup(struct target *target, target_addr_t *ad
/* Write and execute command that moves the value from data0 [, data1]
* into S1 and executes program buffer. */
- uint32_t command = access_register_command(target,
+ uint32_t command = riscv013_access_register_command(target,
GDB_REGNO_S1, riscv_xlen(target),
AC_ACCESS_REGISTER_POSTEXEC |
AC_ACCESS_REGISTER_TRANSFER |
AC_ACCESS_REGISTER_WRITE);
uint32_t cmderr;
- if (execute_abstract_command(target, command, &cmderr) != ERROR_OK)
+ if (riscv013_execute_abstract_command(target, command, &cmderr) != ERROR_OK)
return ERROR_FAIL;
log_memory_access64(*address_p, value, size, /*is_read*/ false);
@@ -5163,6 +4879,18 @@ static int write_memory(struct target *target, target_addr_t address,
return ret;
}
+static bool riscv013_get_impebreak(const struct target *target)
+{
+ RISCV013_INFO(r);
+ return r->impebreak;
+}
+
+static unsigned int riscv013_get_progbufsize(const struct target *target)
+{
+ RISCV013_INFO(r);
+ return r->progbufsize;
+}
+
static int arch_state(struct target *target)
{
return ERROR_OK;
@@ -5515,7 +5243,7 @@ static int riscv013_execute_progbuf(struct target *target, uint32_t *cmderr)
run_program = set_field(run_program, AC_ACCESS_REGISTER_TRANSFER, 0);
run_program = set_field(run_program, AC_ACCESS_REGISTER_REGNO, 0x1000);
- return execute_abstract_command(target, run_program, cmderr);
+ return riscv013_execute_abstract_command(target, run_program, cmderr);
}
static void riscv013_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d)
@@ -5534,7 +5262,7 @@ static void riscv013_fill_dmi_read(struct target *target, char *buf, uint64_t a)
buf_set_u64((unsigned char *)buf, DTM_DMI_ADDRESS_OFFSET, info->abits, a);
}
-static void riscv013_fill_dmi_nop(struct target *target, char *buf)
+static void riscv013_fill_dm_nop(struct target *target, char *buf)
{
RISCV013_INFO(info);
buf_set_u64((unsigned char *)buf, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, DMI_OP_NOP);
@@ -5548,27 +5276,6 @@ static int riscv013_get_dmi_scan_length(struct target *target)
return info->abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH;
}
-void riscv013_fill_dm_write(struct target *target, char *buf, uint64_t a, uint32_t d)
-{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return;
- riscv013_fill_dmi_write(target, buf, a + dm->base, d);
-}
-
-void riscv013_fill_dm_read(struct target *target, char *buf, uint64_t a)
-{
- dm013_info_t *dm = get_dm(target);
- if (!dm)
- return;
- riscv013_fill_dmi_read(target, buf, a + dm->base);
-}
-
-void riscv013_fill_dm_nop(struct target *target, char *buf)
-{
- riscv013_fill_dmi_nop(target, buf);
-}
-
static int maybe_execute_fence_i(struct target *target)
{
if (has_sufficient_progbuf(target, 2))
diff --git a/src/target/riscv/riscv-013.h b/src/target/riscv/riscv-013.h
index be508f7..ca2d4ae 100644
--- a/src/target/riscv/riscv-013.h
+++ b/src/target/riscv/riscv-013.h
@@ -19,5 +19,9 @@ int riscv013_set_register(struct target *target, enum gdb_regno rid,
riscv_reg_t value);
int riscv013_set_register_buf(struct target *target, enum gdb_regno regno,
const uint8_t *value);
+uint32_t riscv013_access_register_command(struct target *target, uint32_t number,
+ unsigned int size, uint32_t flags);
+int riscv013_execute_abstract_command(struct target *target, uint32_t command,
+ uint32_t *cmderr);
-#endif /*OPENOCD_TARGET_RISCV_RISCV_013_H*/
+#endif /* OPENOCD_TARGET_RISCV_RISCV_013_H */
diff --git a/src/target/riscv/riscv-013_reg.c b/src/target/riscv/riscv-013_reg.c
index a71a01c..514103b 100644
--- a/src/target/riscv/riscv-013_reg.c
+++ b/src/target/riscv/riscv-013_reg.c
@@ -5,10 +5,12 @@
#endif
#include "riscv-013_reg.h"
+#include "field_helpers.h"
#include "riscv_reg.h"
#include "riscv_reg_impl.h"
#include "riscv-013.h"
+#include "debug_defines.h"
#include <helper/time_support.h>
static int riscv013_reg_get(struct reg *reg)
@@ -44,7 +46,6 @@ static int riscv013_reg_get(struct reg *reg)
static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
{
struct target *target = riscv_reg_impl_get_target(reg);
- RISCV_INFO(r);
char *str = buf_to_hex_str(buf, reg->size);
LOG_TARGET_DEBUG(target, "Write 0x%s to %s (valid=%d).", str, reg->name,
@@ -57,17 +58,6 @@ static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
buf_get_u64(buf, 0, reg->size) == 0)
return ERROR_OK;
- if (reg->number == GDB_REGNO_TDATA1 ||
- reg->number == GDB_REGNO_TDATA2) {
- r->manual_hwbp_set = true;
- /* When enumerating triggers, we clear any triggers with DMODE set,
- * assuming they were left over from a previous debug session. So make
- * sure that is done before a user might be setting their own triggers.
- */
- if (riscv_enumerate_triggers(target) != ERROR_OK)
- return ERROR_FAIL;
- }
-
if (reg->number >= GDB_REGNO_V0 && reg->number <= GDB_REGNO_V31) {
if (riscv013_set_register_buf(target, reg->number, buf) != ERROR_OK)
return ERROR_FAIL;
@@ -85,33 +75,277 @@ static int riscv013_reg_set(struct reg *reg, uint8_t *buf)
static const struct reg_arch_type *riscv013_gdb_regno_reg_type(uint32_t regno)
{
- static const struct reg_arch_type riscv011_reg_type = {
+ static const struct reg_arch_type riscv013_reg_type = {
.get = riscv013_reg_get,
.set = riscv013_reg_set
};
- return &riscv011_reg_type;
+ return &riscv013_reg_type;
}
-static int riscv013_init_reg(struct target *target, uint32_t regno)
+static int init_cache_entry(struct target *target, uint32_t regno)
+{
+ struct reg * const reg = riscv_reg_impl_cache_entry(target, regno);
+ if (riscv_reg_impl_is_initialized(reg))
+ return ERROR_OK;
+ return riscv_reg_impl_init_cache_entry(target, regno,
+ riscv_reg_impl_gdb_regno_exist(target, regno),
+ riscv013_gdb_regno_reg_type(regno));
+}
+
+/**
+ * Some registers are optional (e.g. "misa"). For such registers it is first
+ * assumed they exist (via "assume_reg_exist()"), then the read is attempted
+ * (via the usual "riscv_reg_get()") and if the read fails, the register is
+ * marked as non-existing (via "riscv_reg_impl_set_exist()").
+ */
+static int assume_reg_exist(struct target *target, uint32_t regno)
{
- return riscv_reg_impl_init_one(target, regno, riscv013_gdb_regno_reg_type(regno));
+ return riscv_reg_impl_init_cache_entry(target, regno,
+ /* exist */ true, riscv013_gdb_regno_reg_type(regno));
}
-int riscv013_reg_init_all(struct target *target)
+static int examine_xlen(struct target *target)
{
- if (riscv_reg_impl_init_cache(target) != ERROR_OK)
+ RISCV_INFO(r);
+ unsigned int cmderr;
+
+ const uint32_t command = riscv013_access_register_command(target,
+ GDB_REGNO_S0, /* size */ 64, AC_ACCESS_REGISTER_TRANSFER);
+ int res = riscv013_execute_abstract_command(target, command, &cmderr);
+ if (res == ERROR_OK) {
+ r->xlen = 64;
+ return ERROR_OK;
+ }
+ if (res == ERROR_TIMEOUT_REACHED)
return ERROR_FAIL;
+ r->xlen = 32;
+
+ return ERROR_OK;
+}
+
+static int examine_vlenb(struct target *target)
+{
+ RISCV_INFO(r);
+
+ /* Reading "vlenb" requires "mstatus.vs" to be set, so "mstatus" should
+ * be accessible.*/
+ int res = init_cache_entry(target, GDB_REGNO_MSTATUS);
+ if (res != ERROR_OK)
+ return res;
+
+ res = assume_reg_exist(target, GDB_REGNO_VLENB);
+ if (res != ERROR_OK)
+ return res;
+
+ riscv_reg_t vlenb_val;
+ if (riscv_reg_get(target, &vlenb_val, GDB_REGNO_VLENB) != ERROR_OK) {
+ if (riscv_supports_extension(target, 'V'))
+ LOG_TARGET_WARNING(target, "Couldn't read vlenb; vector register access won't work.");
+ r->vlenb = 0;
+ return riscv_reg_impl_set_exist(target, GDB_REGNO_VLENB, false);
+ }
+ /* As defined by RISC-V V extension specification:
+ * https://github.com/riscv/riscv-v-spec/blob/2f68ef7256d6ec53e4d2bd7cb12862f406d64e34/v-spec.adoc?plain=1#L67-L72 */
+ const unsigned int vlen_max = 65536;
+ const unsigned int vlenb_max = vlen_max / 8;
+ if (vlenb_val > vlenb_max) {
+ LOG_TARGET_WARNING(target, "'vlenb == %" PRIu64
+ "' is greater than maximum allowed by specification (%u); vector register access won't work.",
+ vlenb_val, vlenb_max);
+ r->vlenb = 0;
+ return ERROR_OK;
+ }
+ assert(vlenb_max <= UINT_MAX);
+ r->vlenb = (unsigned int)vlenb_val;
+
+ LOG_TARGET_INFO(target, "Vector support with vlenb=%u", r->vlenb);
+ return ERROR_OK;
+}
+
+enum misa_mxl {
+ MISA_MXL_INVALID = 0,
+ MISA_MXL_32 = 1,
+ MISA_MXL_64 = 2,
+ MISA_MXL_128 = 3
+};
+
+unsigned int mxl_to_xlen(enum misa_mxl mxl)
+{
+ switch (mxl) {
+ case MISA_MXL_32:
+ return 32;
+ case MISA_MXL_64:
+ return 64;
+ case MISA_MXL_128:
+ return 128;
+ case MISA_MXL_INVALID:
+ assert(0);
+ }
+ return 0;
+}
+
+static int check_misa_mxl(const struct target *target)
+{
+ RISCV_INFO(r);
+
+ if (r->misa == 0) {
+ LOG_TARGET_WARNING(target, "'misa' register is read as zero."
+ "OpenOCD will not be able to determine some hart's capabilities.");
+ return ERROR_OK;
+ }
+ const unsigned int dxlen = riscv_xlen(target);
+ assert(dxlen <= sizeof(riscv_reg_t) * CHAR_BIT);
+ assert(dxlen >= 2);
+ const riscv_reg_t misa_mxl_mask = (riscv_reg_t)0x3 << (dxlen - 2);
+ const unsigned int mxl = get_field(r->misa, misa_mxl_mask);
+ if (mxl == MISA_MXL_INVALID) {
+ /* This is not an error!
+ * Imagine the platform that:
+ * - Has no abstract access to CSRs, so that CSRs are read
+ * through Program Buffer via "csrr" instruction.
+ * - Complies to v1.10 of the Priveleged Spec, so that misa.mxl
+ * is WARL and MXLEN may be chainged.
+ * https://github.com/riscv/riscv-isa-manual/commit/9a7dd2fe29011587954560b5dcf1875477b27ad8
+ * - DXLEN == MXLEN on reset == 64.
+ * In a following scenario:
+ * - misa.mxl was written, so that MXLEN is 32.
+ * - Debugger connects to the target.
+ * - Debugger observes DXLEN == 64.
+ * - Debugger reads misa:
+ * - Abstract access fails with "cmderr == not supported".
+ * - Access via Program Buffer involves reading "misa" to an
+ * "xreg" via "csrr", so that the "xreg" is filled with
+ * zero-extended value of "misa" (since "misa" is
+ * MXLEN-wide).
+ * - Debugger derives "misa.mxl" assumig "misa" is DXLEN-bit
+ * wide (64) while MXLEN is 32 and therefore erroneously
+ * assumes "misa.mxl" to be zero (invalid).
+ */
+ LOG_TARGET_WARNING(target, "Detected DXLEN (%u) does not match "
+ "MXLEN: misa.mxl == 0, misa == 0x%" PRIx64 ".",
+ dxlen, r->misa);
+ return ERROR_OK;
+ }
+ const unsigned int mxlen = mxl_to_xlen(mxl);
+ if (dxlen < mxlen) {
+ LOG_TARGET_ERROR(target,
+ "MXLEN (%u) reported in misa.mxl field exceeds "
+ "the detected DXLEN (%u)",
+ mxlen, dxlen);
+ return ERROR_FAIL;
+ }
+ /* NOTE:
+ * The value of "misa.mxl" may stil not coincide with "xlen".
+ * "misa[26:XLEN-3]" bits are marked as WIRI in at least version 1.10
+ * of RISC-V Priveleged Spec. Therefore, if "xlen" is erroneously
+ * assumed to be 32 when it actually is 64, "mxl" will be read from
+ * this WIRI field and may be equal to "MISA_MXL_32" by coincidence.
+ * This is not an issue though from the version 1.11 onward, since
+ * "misa[26:XLEN-3]" became WARL and equal to 0.
+ */
+
+ /* Display this as early as possible to help people who are using
+ * really slow simulators. */
+ LOG_TARGET_DEBUG(target, " XLEN=%d, misa=0x%" PRIx64, riscv_xlen(target), r->misa);
+ return ERROR_OK;
+}
+
+static int examine_misa(struct target *target)
+{
+ RISCV_INFO(r);
+
+ int res = init_cache_entry(target, GDB_REGNO_MISA);
+ if (res != ERROR_OK)
+ return res;
+
+ res = riscv_reg_get(target, &r->misa, GDB_REGNO_MISA);
+ if (res != ERROR_OK)
+ return res;
+ return check_misa_mxl(target);
+}
+
+static int examine_mtopi(struct target *target)
+{
+ RISCV_INFO(r);
+
+ /* Assume the registers exist */
+ r->mtopi_readable = true;
+ r->mtopei_readable = true;
+
+ int res = assume_reg_exist(target, GDB_REGNO_MTOPI);
+ if (res != ERROR_OK)
+ return res;
+ res = assume_reg_exist(target, GDB_REGNO_MTOPEI);
+ if (res != ERROR_OK)
+ return res;
+
+ riscv_reg_t value;
+ if (riscv_reg_get(target, &value, GDB_REGNO_MTOPI) != ERROR_OK) {
+ r->mtopi_readable = false;
+ r->mtopei_readable = false;
+ } else if (riscv_reg_get(target, &value, GDB_REGNO_MTOPEI) != ERROR_OK) {
+ LOG_TARGET_INFO(target, "S?aia detected without IMSIC");
+ r->mtopei_readable = false;
+ } else {
+ LOG_TARGET_INFO(target, "S?aia detected with IMSIC");
+ }
+ res = riscv_reg_impl_set_exist(target, GDB_REGNO_MTOPI, r->mtopi_readable);
+ if (res != ERROR_OK)
+ return res;
+
+ return riscv_reg_impl_set_exist(target, GDB_REGNO_MTOPEI, r->mtopei_readable);
+}
+
+/**
+ * This function assumes target's DM to be initialized (target is able to
+ * access DMs registers, execute program buffer, etc.)
+ */
+int riscv013_reg_examine_all(struct target *target)
+{
+ int res = riscv_reg_impl_init_cache(target);
+ if (res != ERROR_OK)
+ return res;
init_shared_reg_info(target);
+ assert(target->state == TARGET_HALTED);
+
+ res = examine_xlen(target);
+ if (res != ERROR_OK)
+ return res;
+
+ /* Reading CSRs may clobber "s0", "s1", so it should be possible to
+ * save them in cache. */
+ res = init_cache_entry(target, GDB_REGNO_S0);
+ if (res != ERROR_OK)
+ return res;
+ res = init_cache_entry(target, GDB_REGNO_S1);
+ if (res != ERROR_OK)
+ return res;
+
+ res = examine_misa(target);
+ if (res != ERROR_OK)
+ return res;
+
+ res = examine_vlenb(target);
+ if (res != ERROR_OK)
+ return res;
+
riscv_reg_impl_init_vector_reg_type(target);
- for (uint32_t regno = 0; regno < target->reg_cache->num_regs; ++regno)
- if (riscv013_init_reg(target, regno) != ERROR_OK)
- return ERROR_FAIL;
+ res = examine_mtopi(target);
+ if (res != ERROR_OK)
+ return res;
- if (riscv_reg_impl_expose_csrs(target) != ERROR_OK)
- return ERROR_FAIL;
+ for (uint32_t regno = 0; regno < target->reg_cache->num_regs; ++regno) {
+ res = init_cache_entry(target, regno);
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ res = riscv_reg_impl_expose_csrs(target);
+ if (res != ERROR_OK)
+ return res;
riscv_reg_impl_hide_csrs(target);
diff --git a/src/target/riscv/riscv-013_reg.h b/src/target/riscv/riscv-013_reg.h
index 2bdaaa0..e542a35 100644
--- a/src/target/riscv/riscv-013_reg.h
+++ b/src/target/riscv/riscv-013_reg.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef OPENOCD_TARGET_RISCV_RISCV_REG_013_H
-#define OPENOCD_TARGET_RISCV_RISCV_REG_013_H
+#ifndef OPENOCD_TARGET_RISCV_RISCV_013_REG_H
+#define OPENOCD_TARGET_RISCV_RISCV_013_REG_H
#include "target/target.h"
#include "gdb_regs.h"
@@ -13,10 +13,11 @@
*/
/**
- * Init initialize register cache. After this function all registers can be
- * safely accessed via functions described here and in `riscv_reg.h`.
+ * This function assumes target is halted.
+ * After this function all registers can be safely accessed via functions
+ * described here and in `riscv_reg.h`.
*/
-int riscv013_reg_init_all(struct target *target);
+int riscv013_reg_examine_all(struct target *target);
/**
* This function is used to save the value of a register in cache. The register
@@ -28,4 +29,4 @@ int riscv013_reg_init_all(struct target *target);
*/
int riscv013_reg_save(struct target *target, enum gdb_regno regid);
-#endif /*OPENOCD_TARGET_RISCV_RISCV_REG_013_H*/
+#endif /* OPENOCD_TARGET_RISCV_RISCV_013_REG_H */
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index a57c709..11f3956 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -54,7 +54,8 @@ struct scan_field select_idcode = {
};
static bscan_tunnel_type_t bscan_tunnel_type;
-int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
+#define BSCAN_TUNNEL_IR_WIDTH_NBITS 7
+uint8_t bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
static int bscan_tunnel_ir_id; /* IR ID of the JTAG TAP to access the tunnel. Valid when not 0 */
static const uint8_t bscan_zero[4] = {0};
@@ -67,7 +68,6 @@ static struct scan_field select_user4 = {
};
-static uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */
static struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
{
.num_bits = 3,
@@ -80,8 +80,8 @@ static struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
.in_value = NULL,
},
{
- .num_bits = 7,
- .out_value = bscan_tunneled_ir_width,
+ .num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS,
+ .out_value = &bscan_tunnel_ir_width,
.in_value = NULL,
},
{
@@ -98,8 +98,8 @@ static struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = {
.in_value = NULL,
},
{
- .num_bits = 7,
- .out_value = bscan_tunneled_ir_width,
+ .num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS,
+ .out_value = &bscan_tunnel_ir_width,
.in_value = NULL,
},
{
@@ -300,7 +300,6 @@ void select_dmi_via_bscan(struct target *target)
int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_ptr)
{
/* On BSCAN TAP: Select IR=USER4, issue tunneled IR scan via BSCAN TAP's DR */
- uint8_t tunneled_ir_width[4] = {bscan_tunnel_ir_width};
uint8_t tunneled_dr_width[4] = {32};
uint8_t out_value[5] = {0};
uint8_t in_value[5] = {0};
@@ -316,8 +315,8 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
tunneled_ir[1].num_bits = bscan_tunnel_ir_width;
tunneled_ir[1].out_value = ir_dtmcontrol;
tunneled_ir[1].in_value = NULL;
- tunneled_ir[2].num_bits = 7;
- tunneled_ir[2].out_value = tunneled_ir_width;
+ tunneled_ir[2].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
+ tunneled_ir[2].out_value = &bscan_tunnel_ir_width;
tunneled_ir[2].in_value = NULL;
tunneled_ir[3].num_bits = 1;
tunneled_ir[3].out_value = bscan_zero;
@@ -329,7 +328,7 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
tunneled_dr[1].num_bits = 32 + 1;
tunneled_dr[1].out_value = out_value;
tunneled_dr[1].in_value = in_value;
- tunneled_dr[2].num_bits = 7;
+ tunneled_dr[2].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
tunneled_dr[2].out_value = tunneled_dr_width;
tunneled_dr[2].in_value = NULL;
tunneled_dr[3].num_bits = 1;
@@ -343,8 +342,8 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
tunneled_ir[2].num_bits = bscan_tunnel_ir_width;
tunneled_ir[2].out_value = ir_dtmcontrol;
tunneled_ir[1].in_value = NULL;
- tunneled_ir[1].num_bits = 7;
- tunneled_ir[1].out_value = tunneled_ir_width;
+ tunneled_ir[1].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
+ tunneled_ir[1].out_value = &bscan_tunnel_ir_width;
tunneled_ir[2].in_value = NULL;
tunneled_ir[0].num_bits = 1;
tunneled_ir[0].out_value = bscan_zero;
@@ -383,22 +382,23 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
return ERROR_OK;
}
-static int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr)
+/* TODO: rename "dtmcontrol"-> "dtmcs" */
+int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr)
{
- struct scan_field field;
- uint8_t in_value[4];
- uint8_t out_value[4] = { 0 };
+ uint8_t value[4];
if (bscan_tunnel_ir_width != 0)
return dtmcontrol_scan_via_bscan(target, out, in_ptr);
- buf_set_u32(out_value, 0, 32, out);
+ buf_set_u32(value, 0, 32, out);
jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);
- field.num_bits = 32;
- field.out_value = out_value;
- field.in_value = in_value;
+ struct scan_field field = {
+ .num_bits = 32,
+ .out_value = value,
+ .in_value = in_ptr ? value : NULL
+ };
jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
/* Always return to dbus. */
@@ -406,15 +406,18 @@ static int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr
int retval = jtag_execute_queue();
if (retval != ERROR_OK) {
- LOG_TARGET_ERROR(target, "dtmcontrol scan failed, error code = %d", retval);
+ LOG_TARGET_ERROR(target, "dtmcs scan failed, error code = %d", retval);
return retval;
}
- uint32_t in = buf_get_u32(field.in_value, 0, 32);
- LOG_DEBUG("DTMCONTROL: 0x%x -> 0x%x", out, in);
-
- if (in_ptr)
+ if (in_ptr) {
+ assert(field.in_value);
+ uint32_t in = buf_get_u32(field.in_value, 0, 32);
+ LOG_TARGET_DEBUG(target, "DTMCS: 0x%" PRIx32 " -> 0x%" PRIx32, out, in);
*in_ptr = in;
+ } else {
+ LOG_TARGET_DEBUG(target, "DTMCS: 0x%" PRIx32 " -> ?", out);
+ }
return ERROR_OK;
}
@@ -473,7 +476,6 @@ static int riscv_init_target(struct command_context *cmd_ctx,
}
h_u32_to_le(ir_user4, ir_user4_raw);
select_user4.num_bits = target->tap->ir_length;
- bscan_tunneled_ir_width[0] = bscan_tunnel_ir_width;
if (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)
bscan_tunnel_data_register_select_dmi[1].num_bits = bscan_tunnel_ir_width;
else /* BSCAN_TUNNEL_NESTED_TAP */
@@ -527,6 +529,8 @@ static void riscv_deinit_target(struct target *target)
if (!info)
return;
+ free(info->reserved_triggers);
+
range_list_t *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &info->hide_csr, list) {
free(entry->name);
@@ -620,6 +624,15 @@ static int find_first_trigger_by_id(struct target *target, int unique_id)
static int set_trigger(struct target *target, unsigned int idx, riscv_reg_t tdata1, riscv_reg_t tdata2,
riscv_reg_t tdata1_ignore_mask)
{
+ RISCV_INFO(r);
+ assert(r->reserved_triggers);
+ assert(idx < r->trigger_count);
+ if (r->reserved_triggers[idx]) {
+ LOG_TARGET_DEBUG(target,
+ "Trigger %u is reserved by 'reserve_trigger' command.", idx);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
riscv_reg_t tdata1_rb, tdata2_rb;
// Select which trigger to use
if (riscv_reg_set(target, GDB_REGNO_TSELECT, idx) != ERROR_OK)
@@ -2453,87 +2466,48 @@ static int riscv_deassert_reset(struct target *target)
return tt->deassert_reset(target);
}
-/* state must be riscv_reg_t state[RISCV_MAX_HWBPS] = {0}; */
-static int disable_triggers(struct target *target, riscv_reg_t *state)
+/* "wp_is_set" array must have at least "r->trigger_count" items. */
+static int disable_watchpoints(struct target *target, bool *wp_is_set)
{
RISCV_INFO(r);
-
LOG_TARGET_DEBUG(target, "Disabling triggers.");
- if (riscv_enumerate_triggers(target) != ERROR_OK)
- return ERROR_FAIL;
-
- if (r->manual_hwbp_set) {
- /* Look at every trigger that may have been set. */
- riscv_reg_t tselect;
- if (riscv_reg_get(target, &tselect, GDB_REGNO_TSELECT) != ERROR_OK)
- return ERROR_FAIL;
- for (unsigned int t = 0; t < r->trigger_count; t++) {
- if (riscv_reg_set(target, GDB_REGNO_TSELECT, t) != ERROR_OK)
- return ERROR_FAIL;
- riscv_reg_t tdata1;
- if (riscv_reg_get(target, &tdata1, GDB_REGNO_TDATA1) != ERROR_OK)
+ /* TODO: The algorithm is flawed and may result in a situation described in
+ * https://github.com/riscv-collab/riscv-openocd/issues/1108
+ */
+ memset(wp_is_set, false, r->trigger_count);
+ struct watchpoint *watchpoint = target->watchpoints;
+ int i = 0;
+ while (watchpoint) {
+ LOG_TARGET_DEBUG(target, "Watchpoint %" PRIu32 ": set=%s",
+ watchpoint->unique_id,
+ wp_is_set[i] ? "true" : "false");
+ wp_is_set[i] = watchpoint->is_set;
+ if (watchpoint->is_set) {
+ if (riscv_remove_watchpoint(target, watchpoint) != ERROR_OK)
return ERROR_FAIL;
- if (tdata1 & CSR_TDATA1_DMODE(riscv_xlen(target))) {
- state[t] = tdata1;
- if (riscv_reg_set(target, GDB_REGNO_TDATA1, 0) != ERROR_OK)
- return ERROR_FAIL;
- }
- }
- if (riscv_reg_set(target, GDB_REGNO_TSELECT, tselect) != ERROR_OK)
- return ERROR_FAIL;
-
- } else {
- /* Just go through the triggers we manage. */
- struct watchpoint *watchpoint = target->watchpoints;
- int i = 0;
- while (watchpoint) {
- LOG_TARGET_DEBUG(target, "Watchpoint %d: set=%d", i, watchpoint->is_set);
- state[i] = watchpoint->is_set;
- if (watchpoint->is_set) {
- if (riscv_remove_watchpoint(target, watchpoint) != ERROR_OK)
- return ERROR_FAIL;
- }
- watchpoint = watchpoint->next;
- i++;
}
+ watchpoint = watchpoint->next;
+ i++;
}
return ERROR_OK;
}
-static int enable_triggers(struct target *target, riscv_reg_t *state)
+static int enable_watchpoints(struct target *target, bool *wp_is_set)
{
- RISCV_INFO(r);
-
- if (r->manual_hwbp_set) {
- /* Look at every trigger that may have been set. */
- riscv_reg_t tselect;
- if (riscv_reg_get(target, &tselect, GDB_REGNO_TSELECT) != ERROR_OK)
- return ERROR_FAIL;
- for (unsigned int t = 0; t < r->trigger_count; t++) {
- if (state[t] != 0) {
- if (riscv_reg_set(target, GDB_REGNO_TSELECT, t) != ERROR_OK)
- return ERROR_FAIL;
- if (riscv_reg_set(target, GDB_REGNO_TDATA1, state[t]) != ERROR_OK)
- return ERROR_FAIL;
- }
- }
- if (riscv_reg_set(target, GDB_REGNO_TSELECT, tselect) != ERROR_OK)
- return ERROR_FAIL;
-
- } else {
- struct watchpoint *watchpoint = target->watchpoints;
- int i = 0;
- while (watchpoint) {
- LOG_TARGET_DEBUG(target, "Watchpoint %d: cleared=%" PRId64, i, state[i]);
- if (state[i]) {
- if (riscv_add_watchpoint(target, watchpoint) != ERROR_OK)
- return ERROR_FAIL;
- }
- watchpoint = watchpoint->next;
- i++;
+ struct watchpoint *watchpoint = target->watchpoints;
+ int i = 0;
+ while (watchpoint) {
+ LOG_TARGET_DEBUG(target, "Watchpoint %" PRIu32
+ ": %s to be re-enabled.", watchpoint->unique_id,
+ wp_is_set[i] ? "needs " : "does not need");
+ if (wp_is_set[i]) {
+ if (riscv_add_watchpoint(target, watchpoint) != ERROR_OK)
+ return ERROR_FAIL;
}
+ watchpoint = watchpoint->next;
+ i++;
}
return ERROR_OK;
@@ -3781,9 +3755,16 @@ static int riscv_openocd_step_impl(struct target *target, int current,
return ERROR_FAIL;
}
- riscv_reg_t trigger_state[RISCV_MAX_HWBPS] = {0};
- if (disable_triggers(target, trigger_state) != ERROR_OK)
+ if (riscv_enumerate_triggers(target) != ERROR_OK)
+ return ERROR_FAIL;
+
+ RISCV_INFO(r);
+ bool *wps_to_enable = calloc(r->trigger_count, sizeof(*wps_to_enable));
+ if (disable_watchpoints(target, wps_to_enable) != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Failed to temporarily disable "
+ "watchpoints before single-step.");
return ERROR_FAIL;
+ }
bool success = true;
uint64_t current_mstatus;
@@ -3814,9 +3795,10 @@ static int riscv_openocd_step_impl(struct target *target, int current,
}
_exit:
- if (enable_triggers(target, trigger_state) != ERROR_OK) {
+ if (enable_watchpoints(target, wps_to_enable) != ERROR_OK) {
success = false;
- LOG_TARGET_ERROR(target, "Unable to enable triggers.");
+ LOG_TARGET_ERROR(target, "Failed to re-enable watchpoints "
+ "after single-step.");
}
if (breakpoint && (riscv_add_breakpoint(target, breakpoint) != ERROR_OK)) {
@@ -4382,18 +4364,23 @@ COMMAND_HANDLER(riscv_resume_order)
COMMAND_HANDLER(riscv_use_bscan_tunnel)
{
- int irwidth = 0;
+ uint8_t irwidth = 0;
int tunnel_type = BSCAN_TUNNEL_NESTED_TAP;
- if (CMD_ARGC > 2) {
- LOG_ERROR("Command takes at most two arguments");
+ if (CMD_ARGC < 1 || CMD_ARGC > 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- } else if (CMD_ARGC == 1) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], irwidth);
- } else if (CMD_ARGC == 2) {
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], irwidth);
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tunnel_type);
+
+ if (CMD_ARGC >= 1) {
+ COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], irwidth);
+ assert(BSCAN_TUNNEL_IR_WIDTH_NBITS < 8);
+ if (irwidth >= (uint8_t)1 << BSCAN_TUNNEL_IR_WIDTH_NBITS) {
+ command_print(CMD, "'value' does not fit into %d bits.",
+ BSCAN_TUNNEL_IR_WIDTH_NBITS);
+ return ERROR_COMMAND_ARGUMENT_OVERFLOW;
+ }
}
+ if (CMD_ARGC == 2)
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tunnel_type);
if (tunnel_type == BSCAN_TUNNEL_NESTED_TAP)
LOG_INFO("Nested Tap based Bscan Tunnel Selected");
else if (tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)
@@ -5031,6 +5018,57 @@ COMMAND_HANDLER(riscv_set_enable_trigger_feature)
return ERROR_OK;
}
+static COMMAND_HELPER(report_reserved_triggers, struct target *target)
+{
+ RISCV_INFO(r);
+ if (riscv_enumerate_triggers(target) != ERROR_OK)
+ return ERROR_FAIL;
+ const char *separator = "";
+ for (riscv_reg_t t = 0; t < r->trigger_count; ++t) {
+ if (r->reserved_triggers[t]) {
+ command_print_sameline(CMD, "%s%" PRIu64, separator, t);
+ separator = " ";
+ }
+ }
+ command_print_sameline(CMD, "\n");
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_reserve_trigger)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ if (CMD_ARGC == 0)
+ return CALL_COMMAND_HANDLER(report_reserved_triggers, target);
+
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ riscv_reg_t t;
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], t);
+
+ if (riscv_enumerate_triggers(target) != ERROR_OK)
+ return ERROR_FAIL;
+ RISCV_INFO(r);
+ if (r->trigger_count == 0) {
+ command_print(CMD, "Error: There are no triggers on the target.");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ if (t >= r->trigger_count) {
+ command_print(CMD, "Error: trigger with index %" PRIu64
+ " does not exist. There are only %u triggers"
+ " on the target (with indexes 0 .. %u).",
+ t, r->trigger_count, r->trigger_count - 1);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ if (r->trigger_unique_id[t] != -1) {
+ command_print(CMD, "Error: trigger with index %" PRIu64
+ " is already in use and can not be reserved.", t);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[1], r->reserved_triggers[t]);
+ return ERROR_OK;
+}
+
static const struct command_registration riscv_exec_command_handlers[] = {
{
.name = "dump_sample_buf",
@@ -5195,18 +5233,14 @@ static const struct command_registration riscv_exec_command_handlers[] = {
{
.name = "use_bscan_tunnel",
.handler = riscv_use_bscan_tunnel,
- .mode = COMMAND_ANY,
+ .mode = COMMAND_CONFIG,
.usage = "value [type]",
- .help = "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. Pass A second argument "
- "(optional) to indicate Bscan Tunnel Type {0:(default) NESTED_TAP , "
- "1: DATA_REGISTER}"
+ .help = "Enable or disable use of a BSCAN tunnel to reach DM."
},
{
.name = "set_bscan_tunnel_ir",
.handler = riscv_set_bscan_tunnel_ir,
- .mode = COMMAND_ANY,
+ .mode = COMMAND_CONFIG,
.usage = "value",
.help = "Specify the JTAG TAP IR used to access the bscan tunnel. "
"By default it is 0x23 << (ir_length - 6), which map some "
@@ -5287,6 +5321,14 @@ static const struct command_registration riscv_exec_command_handlers[] = {
.usage = "[('eq'|'napot'|'ge_lt'|'all') ('wp'|'none')]",
.help = "Control whether OpenOCD is allowed to use certain RISC-V trigger features for watchpoints."
},
+ {
+ .name = "reserve_trigger",
+ .handler = handle_reserve_trigger,
+ /* TODO: Move this to COMMAND_ANY */
+ .mode = COMMAND_EXEC,
+ .usage = "[index ('on'|'off')]",
+ .help = "Controls which RISC-V triggers shall not be touched by OpenOCD.",
+ },
COMMAND_REGISTRATION_DONE
};
@@ -5565,7 +5607,7 @@ static enum riscv_halt_reason riscv_halt_reason(struct target *target)
size_t riscv_progbuf_size(struct target *target)
{
RISCV_INFO(r);
- return r->progbuf_size;
+ return r->get_progbufsize(target);
}
int riscv_write_progbuf(struct target *target, int index, riscv_insn_t insn)
@@ -5587,16 +5629,16 @@ int riscv_execute_progbuf(struct target *target, uint32_t *cmderr)
return r->execute_progbuf(target, cmderr);
}
-void riscv_fill_dm_write(struct target *target, char *buf, uint64_t a, uint32_t d)
+void riscv_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d)
{
RISCV_INFO(r);
- r->fill_dm_write(target, buf, a, d);
+ r->fill_dmi_write(target, buf, a, d);
}
-void riscv_fill_dm_read(struct target *target, char *buf, uint64_t a)
+void riscv_fill_dmi_read(struct target *target, char *buf, uint64_t a)
{
RISCV_INFO(r);
- r->fill_dm_read(target, buf, a);
+ r->fill_dmi_read(target, buf, a);
}
void riscv_fill_dm_nop(struct target *target, char *buf)
@@ -5711,6 +5753,8 @@ int riscv_enumerate_triggers(struct target *target)
"Assuming that triggers are not implemented.");
r->triggers_enumerated = true;
r->trigger_count = 0;
+ free(r->reserved_triggers);
+ r->reserved_triggers = NULL;
return ERROR_OK;
}
@@ -5745,6 +5789,8 @@ int riscv_enumerate_triggers(struct target *target)
r->triggers_enumerated = true;
r->trigger_count = t;
LOG_TARGET_INFO(target, "Found %d triggers", r->trigger_count);
+ free(r->reserved_triggers);
+ r->reserved_triggers = calloc(t, sizeof(*r->reserved_triggers));
create_wp_trigger_cache(target);
return ERROR_OK;
}
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 5b75bf6..635e672 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef RISCV_H
-#define RISCV_H
+#ifndef OPENOCD_TARGET_RISCV_RISCV_H
+#define OPENOCD_TARGET_RISCV_RISCV_H
struct riscv_program;
@@ -167,12 +167,6 @@ struct riscv_info {
* most recent halt was not caused by a trigger, then this is -1. */
int64_t trigger_hit;
- /* The number of entries in the program buffer. */
- int progbuf_size;
-
- /* This hart contains an implicit ebreak at the end of the program buffer. */
- bool impebreak;
-
bool triggers_enumerated;
/* Decremented every scan, and when it reaches 0 we clear the learned
@@ -226,8 +220,8 @@ struct riscv_info {
int (*execute_progbuf)(struct target *target, uint32_t *cmderr);
int (*invalidate_cached_progbuf)(struct target *target);
int (*get_dmi_scan_length)(struct target *target);
- void (*fill_dm_write)(struct target *target, char *buf, uint64_t a, uint32_t d);
- void (*fill_dm_read)(struct target *target, char *buf, uint64_t a);
+ void (*fill_dmi_write)(struct target *target, char *buf, uint64_t a, uint32_t d);
+ void (*fill_dmi_read)(struct target *target, char *buf, uint64_t a);
void (*fill_dm_nop)(struct target *target, char *buf);
int (*authdata_read)(struct target *target, uint32_t *value, unsigned int index);
@@ -236,6 +230,9 @@ struct riscv_info {
int (*dmi_read)(struct target *target, uint32_t *value, uint32_t address);
int (*dmi_write)(struct target *target, uint32_t address, uint32_t value);
+ bool (*get_impebreak)(const struct target *target);
+ unsigned int (*get_progbufsize)(const struct target *target);
+
/* Get the DMI address of target's DM's register.
* The function should return the passed address
* if the target is not assigned a DM yet.
@@ -272,9 +269,7 @@ struct riscv_info {
struct reg_data_type_union vector_union;
struct reg_data_type type_vector;
- /* Set when trigger registers are changed by the user. This indicates we need
- * to beware that we may hit a trigger that we didn't realize had been set. */
- bool manual_hwbp_set;
+ bool *reserved_triggers;
/* Memory access methods to use, ordered by priority, highest to lowest. */
int mem_access_methods[RISCV_NUM_MEM_ACCESS_METHODS];
@@ -362,12 +357,13 @@ extern struct scan_field select_dtmcontrol;
extern struct scan_field select_dbus;
extern struct scan_field select_idcode;
+int dtmcontrol_scan(struct target *target, uint32_t out, uint32_t *in_ptr);
+
extern struct scan_field *bscan_tunneled_select_dmi;
extern uint32_t bscan_tunneled_select_dmi_num_fields;
typedef enum { BSCAN_TUNNEL_NESTED_TAP, BSCAN_TUNNEL_DATA_REGISTER } bscan_tunnel_type_t;
-extern int bscan_tunnel_ir_width;
+extern uint8_t bscan_tunnel_ir_width;
-int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_ptr);
void select_dmi_via_bscan(struct target *target);
/*** OpenOCD Interface */
@@ -408,8 +404,8 @@ int riscv_write_progbuf(struct target *target, int index, riscv_insn_t insn);
int riscv_execute_progbuf(struct target *target, uint32_t *cmderr);
void riscv_fill_dm_nop(struct target *target, char *buf);
-void riscv_fill_dm_write(struct target *target, char *buf, uint64_t a, uint32_t d);
-void riscv_fill_dm_read(struct target *target, char *buf, uint64_t a);
+void riscv_fill_dmi_write(struct target *target, char *buf, uint64_t a, uint32_t d);
+void riscv_fill_dmi_read(struct target *target, char *buf, uint64_t a);
int riscv_get_dmi_scan_length(struct target *target);
uint32_t riscv_get_dmi_address(const struct target *target, uint32_t dm_address);
@@ -433,4 +429,4 @@ int riscv_write_by_any_size(struct target *target, target_addr_t address, uint32
int riscv_interrupts_disable(struct target *target, uint64_t ie_mask, uint64_t *old_mstatus);
int riscv_interrupts_restore(struct target *target, uint64_t old_mstatus);
-#endif
+#endif /* OPENOCD_TARGET_RISCV_RISCV_H */
diff --git a/src/target/riscv/riscv_reg.c b/src/target/riscv/riscv_reg.c
index 6cf67dd..4f386f4 100644
--- a/src/target/riscv/riscv_reg.c
+++ b/src/target/riscv/riscv_reg.c
@@ -376,8 +376,19 @@ static bool is_known_standard_csr(unsigned int csr_num)
return is_csr_in_buf[csr_num];
}
-static bool gdb_regno_exist(const struct target *target, uint32_t regno)
-{
+bool riscv_reg_impl_gdb_regno_exist(const struct target *target, uint32_t regno)
+{
+ switch (regno) {
+ case GDB_REGNO_VLENB:
+ case GDB_REGNO_MTOPI:
+ case GDB_REGNO_MTOPEI:
+ assert(false
+ && "Existence of other registers is determined "
+ "depending on existence of these ones, so "
+ "whether these register exist or not should be "
+ "set explicitly.");
+ };
+
if (regno <= GDB_REGNO_XPR15 ||
regno == GDB_REGNO_PC ||
regno == GDB_REGNO_PRIV)
@@ -403,7 +414,6 @@ static bool gdb_regno_exist(const struct target *target, uint32_t regno)
case CSR_VL:
case CSR_VCSR:
case CSR_VTYPE:
- case CSR_VLENB:
return vlenb_exists(target);
case CSR_SCOUNTEREN:
case CSR_SSTATUS:
@@ -599,14 +609,15 @@ static int resize_reg(const struct target *target, uint32_t regno, bool exist,
return ERROR_OK;
}
-static int set_reg_exist(const struct target *target, uint32_t regno, bool exist)
+int riscv_reg_impl_set_exist(const struct target *target, uint32_t regno, bool exist)
{
const struct reg *reg = riscv_reg_impl_cache_entry(target, regno);
assert(riscv_reg_impl_is_initialized(reg));
return resize_reg(target, regno, exist, reg->size);
}
-int riscv_reg_impl_init_one(struct target *target, uint32_t regno, const struct reg_arch_type *reg_type)
+int riscv_reg_impl_init_cache_entry(struct target *target, uint32_t regno,
+ bool exist, const struct reg_arch_type *reg_type)
{
struct reg * const reg = riscv_reg_impl_cache_entry(target, regno);
if (riscv_reg_impl_is_initialized(reg))
@@ -634,8 +645,7 @@ int riscv_reg_impl_init_one(struct target *target, uint32_t regno, const struct
reg_arch_info->target = target;
reg_arch_info->custom_number = gdb_regno_custom_number(target, regno);
}
- return resize_reg(target, regno, gdb_regno_exist(target, regno),
- gdb_regno_size(target, regno));
+ return resize_reg(target, regno, exist, gdb_regno_size(target, regno));
}
static int init_custom_register_names(struct list_head *expose_custom,
@@ -725,7 +735,7 @@ int riscv_reg_impl_expose_csrs(const struct target *target)
csr_number);
continue;
}
- if (set_reg_exist(target, regno, /*exist*/ true) != ERROR_OK)
+ if (riscv_reg_impl_set_exist(target, regno, /*exist*/ true) != ERROR_OK)
return ERROR_FAIL;
LOG_TARGET_DEBUG(target, "Exposing additional CSR %d (name=%s)",
csr_number, reg->name);
@@ -746,7 +756,7 @@ void riscv_reg_impl_hide_csrs(const struct target *target)
struct reg * const reg = riscv_reg_impl_cache_entry(target, regno);
const unsigned int csr_number = regno - GDB_REGNO_CSR0;
if (!reg->exist) {
- LOG_TARGET_WARNING(target,
+ LOG_TARGET_DEBUG(target,
"Not hiding CSR %d: register does not exist.",
csr_number);
continue;
@@ -834,15 +844,8 @@ static int riscv_set_or_write_register(struct target *target,
return riscv_set_or_write_register(target, GDB_REGNO_DCSR, dcsr, write_through);
}
- if (!target->reg_cache) {
- assert(!target_was_examined(target));
- LOG_TARGET_DEBUG(target,
- "No cache, writing to target: %s <- 0x%" PRIx64,
- riscv_reg_gdb_regno_name(target, regid), value);
- return riscv013_set_register(target, regid, value);
- }
-
struct reg *reg = riscv_reg_impl_cache_entry(target, regid);
+ assert(riscv_reg_impl_is_initialized(reg));
if (!reg->exist) {
LOG_TARGET_DEBUG(target, "Register %s does not exist.", reg->name);
@@ -935,21 +938,15 @@ int riscv_reg_get(struct target *target, riscv_reg_t *value,
RISCV_INFO(r);
assert(r);
if (r->dtm_version == DTM_DTMCS_VERSION_0_11)
- return riscv013_get_register(target, value, regid);
+ return riscv011_get_register(target, value, regid);
keep_alive();
if (regid == GDB_REGNO_PC)
return riscv_reg_get(target, value, GDB_REGNO_DPC);
- if (!target->reg_cache) {
- assert(!target_was_examined(target));
- LOG_TARGET_DEBUG(target, "No cache, reading %s from target",
- riscv_reg_gdb_regno_name(target, regid));
- return riscv013_get_register(target, value, regid);
- }
-
struct reg *reg = riscv_reg_impl_cache_entry(target, regid);
+ assert(riscv_reg_impl_is_initialized(reg));
if (!reg->exist) {
LOG_TARGET_DEBUG(target, "Register %s does not exist.", reg->name);
return ERROR_FAIL;
diff --git a/src/target/riscv/riscv_reg_impl.h b/src/target/riscv/riscv_reg_impl.h
index 906a5b6..7a483ad 100644
--- a/src/target/riscv/riscv_reg_impl.h
+++ b/src/target/riscv/riscv_reg_impl.h
@@ -13,7 +13,7 @@
* This file describes the helpers to use during register cache initialization
* of a RISC-V target. Each cache entry proceedes through the following stages:
* - not allocated before `riscv_reg_impl_init_cache()`
- * - not initialized before the call to `riscv_reg_impl_init_one()` with appropriate regno.
+ * - not initialized before the call to `riscv_reg_impl_init_cache_entry()` with appropriate regno.
* - initialized until `riscv_reg_free_all()` is called.
*/
static inline bool riscv_reg_impl_is_initialized(const struct reg *reg)
@@ -37,8 +37,18 @@ static inline bool riscv_reg_impl_is_initialized(const struct reg *reg)
int riscv_reg_impl_init_cache(struct target *target);
/** Initialize register. */
-int riscv_reg_impl_init_one(struct target *target, uint32_t regno,
- const struct reg_arch_type *reg_type);
+int riscv_reg_impl_init_cache_entry(struct target *target, uint32_t regno,
+ bool exist, const struct reg_arch_type *reg_type);
+
+/**
+ * For most registers, returns whether they exist or not.
+ * For some registers the "exist" bit should be set explicitly.
+ */
+bool riscv_reg_impl_gdb_regno_exist(const struct target *target, uint32_t regno);
+
+/** Mark register as existing or not. */
+int riscv_reg_impl_set_exist(const struct target *target,
+ uint32_t regno, bool exist);
/** Return the entry in the register cache of the target. */
struct reg *riscv_reg_impl_cache_entry(const struct target *target,
diff --git a/src/target/target.c b/src/target/target.c
index fd9c34f..b51f066 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -3125,11 +3125,18 @@ COMMAND_HANDLER(handle_reg_command)
/* set register value */
if (CMD_ARGC == 2) {
uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));
- if (!buf)
+ if (!buf) {
+ LOG_ERROR("Failed to allocate memory");
return ERROR_FAIL;
- str_to_buf(CMD_ARGV[1], strlen(CMD_ARGV[1]), buf, reg->size, 0);
+ }
+
+ int retval = CALL_COMMAND_HANDLER(command_parse_str_to_buf, CMD_ARGV[1], buf, reg->size, 0);
+ if (retval != ERROR_OK) {
+ free(buf);
+ return retval;
+ }
- int retval = reg->type->set(reg, buf);
+ retval = reg->type->set(reg, buf);
if (retval != ERROR_OK) {
LOG_ERROR("Could not write to register '%s'", reg->name);
} else {
@@ -3898,7 +3905,7 @@ static int handle_bp_command_list(struct command_invocation *cmd)
while (breakpoint) {
if (breakpoint->type == BKPT_SOFT) {
char *buf = buf_to_hex_str(breakpoint->orig_instr,
- breakpoint->length);
+ breakpoint->length * 8);
command_print(cmd, "Software breakpoint(IVA): addr=" TARGET_ADDR_FMT ", len=0x%x, orig_instr=0x%s",
breakpoint->address,
breakpoint->length,
@@ -4772,63 +4779,64 @@ static int target_jim_get_reg(Jim_Interp *interp, int argc,
return JIM_OK;
}
-static int target_jim_set_reg(Jim_Interp *interp, int argc,
- Jim_Obj * const *argv)
+COMMAND_HANDLER(handle_set_reg_command)
{
- if (argc != 2) {
- Jim_WrongNumArgs(interp, 1, argv, "dict");
- return JIM_ERR;
- }
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
int tmp;
#if JIM_VERSION >= 80
- Jim_Obj **dict = Jim_DictPairs(interp, argv[1], &tmp);
+ Jim_Obj **dict = Jim_DictPairs(CMD_CTX->interp, CMD_JIMTCL_ARGV[0], &tmp);
if (!dict)
- return JIM_ERR;
+ return ERROR_FAIL;
#else
Jim_Obj **dict;
- int ret = Jim_DictPairs(interp, argv[1], &dict, &tmp);
+ int ret = Jim_DictPairs(CMD_CTX->interp, CMD_JIMTCL_ARGV[0], &dict, &tmp);
if (ret != JIM_OK)
- return ret;
+ return ERROR_FAIL;
#endif
const unsigned int length = tmp;
- struct command_context *cmd_ctx = current_command_context(interp);
- assert(cmd_ctx);
- const struct target *target = get_current_target(cmd_ctx);
+
+ const struct target *target = get_current_target(CMD_CTX);
+ assert(target);
for (unsigned int i = 0; i < length; i += 2) {
const char *reg_name = Jim_String(dict[i]);
const char *reg_value = Jim_String(dict[i + 1]);
- struct reg *reg = register_get_by_name(target->reg_cache, reg_name,
- false);
+ struct reg *reg = register_get_by_name(target->reg_cache, reg_name, false);
if (!reg || !reg->exist) {
- Jim_SetResultFormatted(interp, "unknown register '%s'", reg_name);
- return JIM_ERR;
+ command_print(CMD, "unknown register '%s'", reg_name);
+ return ERROR_FAIL;
}
uint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));
-
if (!buf) {
LOG_ERROR("Failed to allocate memory");
- return JIM_ERR;
+ return ERROR_FAIL;
}
- str_to_buf(reg_value, strlen(reg_value), buf, reg->size, 0);
- int retval = reg->type->set(reg, buf);
+ int retval = CALL_COMMAND_HANDLER(command_parse_str_to_buf,
+ reg_value, buf, reg->size, 0);
+ if (retval != ERROR_OK) {
+ free(buf);
+ return retval;
+ }
+
+ retval = reg->type->set(reg, buf);
free(buf);
if (retval != ERROR_OK) {
- Jim_SetResultFormatted(interp, "failed to set '%s' to register '%s'",
+ command_print(CMD, "failed to set '%s' to register '%s'",
reg_value, reg_name);
- return JIM_ERR;
+ return retval;
}
}
- return JIM_OK;
+ return ERROR_OK;
}
/**
@@ -5568,7 +5576,7 @@ static const struct command_registration target_instance_command_handlers[] = {
{
.name = "set_reg",
.mode = COMMAND_EXEC,
- .jim_handler = target_jim_set_reg,
+ .handler = handle_set_reg_command,
.help = "Set target register values",
.usage = "dict",
},
@@ -5789,7 +5797,7 @@ static int target_create(struct jim_getopt_info *goi)
}
target->dbgmsg = NULL;
- target->dbg_msg_enabled = 0;
+ target->dbg_msg_enabled = false;
target->endianness = TARGET_ENDIAN_UNKNOWN;
@@ -6703,7 +6711,7 @@ static const struct command_registration target_exec_command_handlers[] = {
{
.name = "set_reg",
.mode = COMMAND_EXEC,
- .jim_handler = target_jim_set_reg,
+ .handler = handle_set_reg_command,
.help = "Set target register values",
.usage = "dict",
},
diff --git a/src/target/target.h b/src/target/target.h
index c74b8c2..9ff2f78 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -163,7 +163,7 @@ struct target {
struct watchpoint *watchpoints; /* list of watchpoints */
struct trace *trace_info; /* generic trace information */
struct debug_msg_receiver *dbgmsg; /* list of debug message receivers */
- uint32_t dbg_msg_enabled; /* debug message status */
+ bool dbg_msg_enabled; /* debug message status */
void *arch_info; /* architecture specific information */
void *private_config; /* pointer to target specific config data (for jim_configure hook) */
struct target *next; /* next target in list */
@@ -805,6 +805,7 @@ int target_profiling_default(struct target *target, uint32_t *samples, uint32_t
#define ERROR_TARGET_ALGO_EXIT (-313)
#define ERROR_TARGET_SIZE_NOT_SUPPORTED (-314)
#define ERROR_TARGET_PACKING_NOT_SUPPORTED (-315)
+#define ERROR_TARGET_HALTED_DO_RESUME (-316) /* used to workaround incorrect debug halt */
extern bool get_target_reset_nag(void);
diff --git a/src/target/target_request.c b/src/target/target_request.c
index 72c8421..bccae07 100644
--- a/src/target/target_request.c
+++ b/src/target/target_request.c
@@ -164,7 +164,7 @@ static int add_debug_msg_receiver(struct command_context *cmd_ctx, struct target
(*p)->next = NULL;
/* enable callback */
- target->dbg_msg_enabled = 1;
+ target->dbg_msg_enabled = true;
return ERROR_OK;
}
@@ -225,7 +225,7 @@ int delete_debug_msg_receiver(struct command_context *cmd_ctx, struct target *ta
free(c);
if (!*p) {
/* disable callback */
- target->dbg_msg_enabled = 0;
+ target->dbg_msg_enabled = false;
}
return ERROR_OK;
} else
diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c
index 702b8fc..8369cc4 100644
--- a/src/target/xtensa/xtensa.c
+++ b/src/target/xtensa/xtensa.c
@@ -540,7 +540,7 @@ static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint
for (int32_t i = oplenw - 1; i > 0; i--)
xtensa_queue_dbg_reg_write(xtensa,
XDMREG_DIR0 + i,
- target_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t)*i]));
+ target_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t) * i]));
/* Write DIR0EXEC last */
xtensa_queue_dbg_reg_write(xtensa,
XDMREG_DIR0EXEC,
@@ -3966,10 +3966,10 @@ COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)
rptr->type = XT_REG_OTHER;
}
- /* Register flags */
+ /* Register flags: includes intsetN, intclearN for LX8 */
if ((strcmp(rptr->name, "mmid") == 0) || (strcmp(rptr->name, "eraccess") == 0) ||
- (strcmp(rptr->name, "ddr") == 0) || (strcmp(rptr->name, "intset") == 0) ||
- (strcmp(rptr->name, "intclear") == 0))
+ (strcmp(rptr->name, "ddr") == 0) || (strncmp(rptr->name, "intset", 6) == 0) ||
+ (strncmp(rptr->name, "intclear", 8) == 0) || (strcmp(rptr->name, "mesrclr") == 0))
rptr->flags = XT_REGF_NOREAD;
else
rptr->flags = 0;
diff --git a/src/target/xtensa/xtensa_chip.c b/src/target/xtensa/xtensa_chip.c
index ac4a49c..ce6d35c 100644
--- a/src/target/xtensa/xtensa_chip.c
+++ b/src/target/xtensa/xtensa_chip.c
@@ -103,7 +103,7 @@ static int xtensa_chip_target_create(struct target *target, Jim_Interp *interp)
LOG_DEBUG("DAP: ap_num %" PRId64 " DAP %p\n", pc->ap_num, pc->dap);
} else {
xtensa_chip_dm_cfg.tap = target->tap;
- LOG_DEBUG("JTAG: %s:%s pos %d", target->tap->chip, target->tap->tapname,
+ LOG_DEBUG("JTAG: %s:%s pos %u", target->tap->chip, target->tap->tapname,
target->tap->abs_chain_position);
}
diff --git a/src/transport/transport.c b/src/transport/transport.c
index 81d3d58..bf306e7 100644
--- a/src/transport/transport.c
+++ b/src/transport/transport.c
@@ -278,7 +278,6 @@ COMMAND_HANDLER(handle_transport_select)
if (session) {
if (!strcmp(session->name, CMD_ARGV[0])) {
LOG_WARNING("Transport \"%s\" was already selected", session->name);
- command_print(CMD, "%s", session->name);
return ERROR_OK;
}
command_print(CMD, "Can't change session's transport after the initial selection was made");
@@ -301,7 +300,6 @@ COMMAND_HANDLER(handle_transport_select)
int retval = transport_select(CMD_CTX, CMD_ARGV[0]);
if (retval != ERROR_OK)
return retval;
- command_print(CMD, "%s", session->name);
return ERROR_OK;
}
}
diff --git a/tcl/board/actux3.cfg b/tcl/board/actux3.cfg
index edb529c..7c2ce06 100644
--- a/tcl/board/actux3.cfg
+++ b/tcl/board/actux3.cfg
@@ -50,7 +50,7 @@ reset init
# setup to debug u-boot in flash
proc uboot_debug {} {
- gdb_breakpoint_override hard
+ gdb breakpoint_override hard
xscale vector_catch 0xFF
xscale vector_table low 1 0xe59ff018
diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg
index 4740471..22a38a7 100644
--- a/tcl/board/at91sam9g20-ek.cfg
+++ b/tcl/board/at91sam9g20-ek.cfg
@@ -43,7 +43,7 @@ proc read_register {register} {
proc at91sam9g20_reset_start { } {
- # Make sure that the the jtag is running slow, since there are a number of different ways the board
+ # Make sure that the jtag is running slow, since there are a number of different ways the board
# can be configured coming into this state that can cause communication problems with the jtag
# adapter. Also since this call can be made following a "reset init" where fast memory accesses
# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower
@@ -202,7 +202,7 @@ proc at91sam9g20_reset_init { } {
mww 0xffffea00 0x3
mww 0x20000000 0
- # Signal normal mode using the SDRAMC_MR register and follow with a zero value write the the starting
+ # Signal normal mode using the SDRAMC_MR register and follow with a zero value write the starting
# memory location for the SDRAM.
mww 0xffffea00 0x0
diff --git a/tcl/board/mini2440.cfg b/tcl/board/mini2440.cfg
index 85d9a35..5642cb1 100644
--- a/tcl/board/mini2440.cfg
+++ b/tcl/board/mini2440.cfg
@@ -128,7 +128,7 @@ reset_config trst_and_srst
# GDB Setup
#-------------------------------------------------------------------------
- gdb_breakpoint_override hard
+ gdb breakpoint_override hard
#------------------------------------------------
# ARM SPECIFIC
diff --git a/tcl/board/mini6410.cfg b/tcl/board/mini6410.cfg
index 18f9e8d..276e718 100644
--- a/tcl/board/mini6410.cfg
+++ b/tcl/board/mini6410.cfg
@@ -95,7 +95,7 @@ adapter srst delay 100
jtag_ntrst_delay 100
reset_config trst_and_srst
-gdb_breakpoint_override hard
+gdb breakpoint_override hard
targets
nand device $_CHIPNAME.flash s3c6400 $_CHIPNAME.cpu
diff --git a/tcl/board/netgear-wg102.cfg b/tcl/board/netgear-wg102.cfg
index 15f9c11..0a7dad5 100644
--- a/tcl/board/netgear-wg102.cfg
+++ b/tcl/board/netgear-wg102.cfg
@@ -27,7 +27,7 @@ $_TARGETNAME configure -event reset-init {
# 0x00003800 - 0x07 << FLASHCTL_WST2_S
# FLASHCTL_AC_8M 0x00060000 - Size of flash
# FLASHCTL_E 0x00080000 - Flash bank enable (added)
- # FLASHCTL_WP 0x04000000 - write protect. If used, CFI mode wont work!!
+ # FLASHCTL_WP 0x04000000 - write protect. If used, CFI mode won't work!!
# FLASHCTL_MWx16 0x10000000 - 16bit mode. Do not use it!!
# FLASHCTL_MWx8 0x00000000 - 8bit mode.
mww 0xb8400000 0x000d3ce1
diff --git a/tcl/board/or1k_generic.cfg b/tcl/board/or1k_generic.cfg
index 915a0de..b6cf3a0 100644
--- a/tcl/board/or1k_generic.cfg
+++ b/tcl/board/or1k_generic.cfg
@@ -22,7 +22,7 @@ poll_period 1
adapter speed 3000
# Enable the target description feature
-gdb_target_description enable
+gdb target_description enable
# Add a new register in the cpu register list. This register will be
# included in the generated target descriptor file.
diff --git a/tcl/board/ti_am62a7_swd_native.cfg b/tcl/board/ti_am62a7_swd_native.cfg
new file mode 100644
index 0000000..99fc0b0
--- /dev/null
+++ b/tcl/board/ti_am62a7_swd_native.cfg
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments AM62A7
+# Link: https://www.ti.com/product/AM62A7
+#
+# This configuration file is used as a self hosted debug configuration that
+# works on every AM62A7 platform based on firewall configuration permitted
+# in the system.
+#
+# In this system openOCD runs on one of the CPUs inside AM62A7 and provides
+# network ports that can then be used to debug the microcontrollers on the
+# SoC - either self hosted IDE OR remotely.
+
+# We are using dmem, which uses dapdirect_swd transport
+adapter driver dmem
+
+if { ![info exists SOC] } {
+ set SOC am62a7
+}
+
+source [find target/ti_k3.cfg]
diff --git a/tcl/board/ti_am62p_swd_native.cfg b/tcl/board/ti_am62p_swd_native.cfg
new file mode 100644
index 0000000..fa549f3
--- /dev/null
+++ b/tcl/board/ti_am62p_swd_native.cfg
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments am62p
+# Link: https://www.ti.com/product/AM62P
+#
+# This configuration file is used as a self hosted debug configuration that
+# works on every AM62P platform based on firewall configuration permitted
+# in the system.
+#
+# In this system openOCD runs on one of the CPUs inside AM62P and provides
+# network ports that can then be used to debug the microcontrollers on the
+# SoC - either self hosted IDE OR remotely.
+
+# We are using dmem, which uses dapdirect_swd transport
+adapter driver dmem
+
+if { ![info exists SOC] } {
+ set SOC am62p
+}
+
+source [find target/ti_k3.cfg]
diff --git a/tcl/board/ti_j722s_swd_native.cfg b/tcl/board/ti_j722s_swd_native.cfg
new file mode 100644
index 0000000..bbe0d50
--- /dev/null
+++ b/tcl/board/ti_j722s_swd_native.cfg
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments J722S/AM67/TDA4VEN
+# Link: https://www.ti.com/product/AM67
+# Link: https://www.ti.com/product/TDA4VEN-Q1
+#
+# This configuration file is used as a self hosted debug configuration that
+# works on every J722S platform based on firewall configuration permitted
+# in the system.
+#
+# In this system openOCD runs on one of the CPUs inside J722S and provides
+# network ports that can then be used to debug the microcontrollers on the
+# SoC - either self hosted IDE OR remotely.
+
+# We are using dmem, which uses dapdirect_swd transport
+adapter driver dmem
+
+if { ![info exists SOC] } {
+ set SOC j722s
+}
+
+source [find target/ti_k3.cfg]
diff --git a/tcl/interface/nulink.cfg b/tcl/interface/nulink.cfg
index 2a4bc0b..48dc20e 100644
--- a/tcl/interface/nulink.cfg
+++ b/tcl/interface/nulink.cfg
@@ -5,9 +5,9 @@
#
adapter driver hla
-hla_layout nulink
-hla_device_desc "Nu-Link"
-hla_vid_pid 0x0416 0x511b 0x0416 0x511c 0x0416 0x511d 0x0416 0x5200 0x0416 0x5201
+hla layout nulink
+hla device_desc "Nu-Link"
+hla vid_pid 0x0416 0x511b 0x0416 0x511c 0x0416 0x511d 0x0416 0x5200 0x0416 0x5201
# Only swd is supported
transport select hla_swd
diff --git a/tcl/interface/raspberrypi5-gpiod.cfg b/tcl/interface/raspberrypi5-gpiod.cfg
index f3fdde0..9624ad5 100644
--- a/tcl/interface/raspberrypi5-gpiod.cfg
+++ b/tcl/interface/raspberrypi5-gpiod.cfg
@@ -19,8 +19,7 @@ proc read_file { name } {
}
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 "*<performance>*" [string map { "\[" < "\]" > } $pcie_aspm]]} {
+if {![string match {*\[performance\]*} $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'"
}
diff --git a/tcl/interface/stlink.cfg b/tcl/interface/stlink.cfg
index 8578bf2..9b7f1f9 100644
--- a/tcl/interface/stlink.cfg
+++ b/tcl/interface/stlink.cfg
@@ -6,9 +6,9 @@
#
adapter driver hla
-hla_layout stlink
-hla_device_desc "ST-LINK"
-hla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757
+hla layout stlink
+hla device_desc "ST-LINK"
+hla vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757
# Optionally specify the serial number of ST-LINK/V2 usb device. ST-LINK/V2
# devices seem to have serial numbers with unreadable characters. ST-LINK/V2
diff --git a/tcl/interface/ti-icdi.cfg b/tcl/interface/ti-icdi.cfg
index db4e1e0..c13d27e 100644
--- a/tcl/interface/ti-icdi.cfg
+++ b/tcl/interface/ti-icdi.cfg
@@ -10,8 +10,8 @@
#
adapter driver hla
-hla_layout ti-icdi
-hla_vid_pid 0x1cbe 0x00fd
+hla layout ti-icdi
+hla vid_pid 0x1cbe 0x00fd
# Optionally specify the serial number of TI-ICDI devices, for when using
# multiple devices. Serial numbers can be obtained using lsusb -v
diff --git a/tcl/interface/vdebug.cfg b/tcl/interface/vdebug.cfg
index 7350bb9..9097c33 100644
--- a/tcl/interface/vdebug.cfg
+++ b/tcl/interface/vdebug.cfg
@@ -22,9 +22,9 @@ vdebug server $_VDEBUGHOST:$_VDEBUGPORT
# example config listen on all interfaces, disable tcl/telnet server
bindto 0.0.0.0
-#gdb_port 3333
+#gdb port 3333
#telnet_port disabled
-tcl_port disabled
+tcl port disabled
# transaction batching: 0 - no batching, 1 - (default) wr, 2 - rw
vdebug batching 1
diff --git a/tcl/target/allwinner_v3s.cfg b/tcl/target/allwinner_v3s.cfg
index 437bd95..6c3435e 100644
--- a/tcl/target/allwinner_v3s.cfg
+++ b/tcl/target/allwinner_v3s.cfg
@@ -28,7 +28,7 @@
# UART2_TX PB0 Per default disabled
# UART2_RX PB1 Per default disabled
#
-# JTAG is enabled by default after power on on listed JTAG_* pins. So far the
+# JTAG is enabled by default after power-on on listed JTAG_* pins. So far the
# boot sequence is:
# Time Action
# 0000ms Power ON
diff --git a/tcl/target/ampere_emag.cfg b/tcl/target/ampere_emag.cfg
index 0b0bd9e..fd68fcd 100644
--- a/tcl/target/ampere_emag.cfg
+++ b/tcl/target/ampere_emag.cfg
@@ -8,7 +8,7 @@
#
# Configure defaults for target
-# Can be overriden in board configuration file
+# Can be overridden in board configuration file
#
if { [info exists CHIPNAME] } {
diff --git a/tcl/target/bl702.cfg b/tcl/target/bl702.cfg
new file mode 100644
index 0000000..6d4a048
--- /dev/null
+++ b/tcl/target/bl702.cfg
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+#
+# Bouffalo Labs BL702, BL704 and BL706 target
+#
+# https://en.bouffalolab.com/product/?type=detail&id=8
+#
+# Default JTAG pins: (if not changed by eFuse configuration)
+# TMS - GPIO0
+# TDI - GPIO1
+# TCK - GPIO2
+# TDO - GPIO9
+#
+
+source [find mem_helper.tcl]
+
+transport select jtag
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME bl702
+}
+
+jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000e05
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME riscv -chain-position $_TARGETNAME
+
+riscv set_mem_access sysbus
+
+$_TARGETNAME configure -work-area-phys 0x22020000 -work-area-size 0x10000 -work-area-backup 1
+
+# Internal RC ticks on 32 MHz, so this speed should be safe to use.
+adapter speed 4000
+
+$_TARGETNAME configure -event reset-assert-pre {
+ halt
+
+ # Switch clock to internal RC32M
+ # In HBN_GLB, set ROOT_CLK_SEL = 0
+ mmw 0x4000f030 0x0 0x00000003
+ # Wait for clock switch
+ sleep 10
+
+ # GLB_REG_BCLK_DIS_FALSE
+ mww 0x40000ffc 0x0
+
+ # HCLK is RC32M, so BCLK/HCLK doesn't need divider
+ # In GLB_CLK_CFG0, set BCLK_DIV = 0 and HCLK_DIV = 0
+ mmw 0x40000000 0x0 0x00FFFF00
+ # Wait for clock to stabilize
+ sleep 10
+
+ # Do reset
+ # In GLB_SWRST_CFG2, clear CTRL_SYS_RESET, CTRL_CPU_RESET and CTRL_PWRON_RESET
+ mmw 0x40000018 0x0 0x00000007
+ # In GLB_SWRST_CFG2, set CTRL_SYS_RESET, CTRL_CPU_RESET and CTRL_PWRON_RESET to 1
+ mmw 0x40000018 0x6 0x0
+}
diff --git a/tcl/target/esi32xx.cfg b/tcl/target/esi32xx.cfg
index a8b0823..d29c636 100644
--- a/tcl/target/esi32xx.cfg
+++ b/tcl/target/esi32xx.cfg
@@ -35,4 +35,4 @@ reset_config none
# The default linker scripts provided by the eSi-RISC toolchain do not
# specify attributes on memory regions, which results in incorrect
# application of software breakpoints by GDB.
-gdb_breakpoint_override hard
+gdb breakpoint_override hard
diff --git a/tcl/target/esp_common.cfg b/tcl/target/esp_common.cfg
index af2f6ad..5ea9bc8 100644
--- a/tcl/target/esp_common.cfg
+++ b/tcl/target/esp_common.cfg
@@ -200,7 +200,7 @@ proc configure_esp_xtensa_default_settings { } {
$_TARGETNAME_0 xtensa smpbreak BreakIn BreakOut
}
- gdb_breakpoint_override hard
+ gdb breakpoint_override hard
if { [info exists _FLASH_VOLTAGE] } {
$_TARGETNAME_0 $_CHIPNAME flashbootstrap $_FLASH_VOLTAGE
diff --git a/tcl/target/icepick.cfg b/tcl/target/icepick.cfg
index 5509532..e5d5706 100644
--- a/tcl/target/icepick.cfg
+++ b/tcl/target/icepick.cfg
@@ -6,7 +6,7 @@
#
# Utilities for TI ICEpick-C/D used in most TI SoCs
-# Details about the ICEPick are available in the the TRM for each SoC
+# Details about the ICEPick are available in the TRM for each SoC
# and http://processors.wiki.ti.com/index.php/ICEPICK
# create "constants"
diff --git a/tcl/target/omap4430.cfg b/tcl/target/omap4430.cfg
index a448550..4bc7fe1 100644
--- a/tcl/target/omap4430.cfg
+++ b/tcl/target/omap4430.cfg
@@ -128,4 +128,4 @@ $_CHIPNAME.m30 configure -event reset-assert { }
$_CHIPNAME.m31 configure -event reset-assert { }
# Soft breakpoints don't currently work due to broken cache handling
-gdb_breakpoint_override hard
+gdb breakpoint_override hard
diff --git a/tcl/target/omap4460.cfg b/tcl/target/omap4460.cfg
index bbc824b..85ba96c 100644
--- a/tcl/target/omap4460.cfg
+++ b/tcl/target/omap4460.cfg
@@ -128,4 +128,4 @@ $_CHIPNAME.m30 configure -event reset-assert { }
$_CHIPNAME.m31 configure -event reset-assert { }
# Soft breakpoints don't currently work due to broken cache handling
-gdb_breakpoint_override hard
+gdb breakpoint_override hard
diff --git a/tcl/target/omapl138.cfg b/tcl/target/omapl138.cfg
index 2d670b9..78c456d 100644
--- a/tcl/target/omapl138.cfg
+++ b/tcl/target/omapl138.cfg
@@ -64,5 +64,5 @@ arm7_9 dcc_downloads enable
etm config $_TARGETNAME 16 normal full etb
etb config $_TARGETNAME $_CHIPNAME.etb
-gdb_breakpoint_override hard
+gdb breakpoint_override hard
arm7_9 dbgrq enable
diff --git a/tcl/target/psoc6.cfg b/tcl/target/psoc6.cfg
index d69515c..52b04f5 100644
--- a/tcl/target/psoc6.cfg
+++ b/tcl/target/psoc6.cfg
@@ -113,7 +113,7 @@ proc psoc6_deassert_post { target } {
}
if { $_ENABLE_CM0 } {
- target create ${TARGET}.cm0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0
+ target create ${TARGET}.cm0 cortex_m -dap $_CHIPNAME.dap -ap-num 1
${TARGET}.cm0 configure -work-area-phys $_WORKAREAADDR_CM0 -work-area-size $_WORKAREASIZE_CM0 -work-area-backup 0
flash bank main_flash_cm0 psoc6 0x10000000 0 0 0 ${TARGET}.cm0
@@ -128,7 +128,7 @@ if { $_ENABLE_CM0 } {
}
if { $_ENABLE_CM4 } {
- target create ${TARGET}.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1
+ target create ${TARGET}.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2
${TARGET}.cm4 configure -work-area-phys $_WORKAREAADDR_CM4 -work-area-size $_WORKAREASIZE_CM4 -work-area-backup 0
flash bank main_flash_cm4 psoc6 0x10000000 0 0 0 ${TARGET}.cm4
diff --git a/tcl/target/rp2040.cfg b/tcl/target/rp2040.cfg
index de76b4e..5e78c69 100644
--- a/tcl/target/rp2040.cfg
+++ b/tcl/target/rp2040.cfg
@@ -96,7 +96,7 @@ if { $_USE_CORE == 1 } {
set _FLASH_TARGET $_TARGETNAME_0
}
# Backup the work area. The flash probe runs an algorithm on the target CPU.
-# The flash is probed during gdb connect if gdb_memory_map is enabled (by default).
+# The flash is probed during gdb connect if gdb memory_map is enabled (by default).
$_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup 1
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME rp2040_flash 0x10000000 0 0 0 $_FLASH_TARGET
diff --git a/tcl/target/ti_k3.cfg b/tcl/target/ti_k3.cfg
index ebea821..2ae0f75 100644
--- a/tcl/target/ti_k3.cfg
+++ b/tcl/target/ti_k3.cfg
@@ -209,6 +209,16 @@ switch $_soc {
# Sysctrl power-ap unlock offsets
set _sysctrl_ap_unlock_offsets {0xf0 0x78}
+ # Setup DMEM access descriptions
+ # DAPBUS (Debugger) description
+ set _dmem_base_address 0x740002000
+ set _dmem_ap_address_offset 0x100
+ set _dmem_max_aps 10
+ # Emulated AP description
+ set _dmem_emu_base_address 0x760000000
+ set _dmem_emu_base_address_map_to 0x1d500000
+ set _dmem_emu_ap_list 1
+
# Overrides for am62p
if { "$_soc" == "am62p" } {
set _K3_DAP_TAPID 0x0bb9d02f
diff --git a/tcl/target/u8500.cfg b/tcl/target/u8500.cfg
index 417fdd1..b87d261 100644
--- a/tcl/target/u8500.cfg
+++ b/tcl/target/u8500.cfg
@@ -142,9 +142,9 @@ proc enable_apetap {} {
}
}
-tcl_port 5555
+tcl port 5555
telnet_port 4444
-gdb_port 3333
+gdb port 3333
if { [info exists CHIPNAME] } {
global _CHIPNAME
@@ -319,7 +319,7 @@ global _MAXSPEED
adapter speed $_MAXSPEED
-gdb_breakpoint_override hard
+gdb breakpoint_override hard
set mem inaccessible-by-default-off
jtag_ntrst_delay 100
diff --git a/tcl/target/xtensa.cfg b/tcl/target/xtensa.cfg
index 561131d..c277673 100644
--- a/tcl/target/xtensa.cfg
+++ b/tcl/target/xtensa.cfg
@@ -67,4 +67,4 @@ if { $_XTENSA_NUM_CORES == 1 } {
$_TARGETNAME configure -event reset-assert-post { soft_reset_halt }
}
-gdb_report_register_access_error enable
+gdb report_register_access_error enable
diff --git a/tools/scripts/checkpatch.pl b/tools/scripts/checkpatch.pl
index 9dda61c..26589be 100755
--- a/tools/scripts/checkpatch.pl
+++ b/tools/scripts/checkpatch.pl
@@ -3769,7 +3769,11 @@ sub process {
}
# check we are in a valid source file if not then ignore this hunk
+ if (!$OpenOCD) {
next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
+ } else { # !$OpenOCD
+ next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts|tcl|cfg|ac|am)$/);
+ } # !$OpenOCD
# check for using SPDX-License-Identifier on the wrong line number
if ($realline != $checklicenseline &&
diff --git a/uncrustify.cfg b/uncrustify.cfg
index 07d0978..593bcc2 100644
--- a/uncrustify.cfg
+++ b/uncrustify.cfg
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
tok_split_gte=false
utf8_byte=false
utf8_force=false